mirror of
https://github.com/etesync/android
synced 2025-01-11 00:01:12 +00:00
Crypto: refactor the Cipher class.
Include the hmac in the cipher class. Derive keys on class creation instead of on encrypt/decrypt.
This commit is contained in:
parent
0fbee1ea02
commit
abd13d4d3d
@ -1,5 +1,8 @@
|
||||
package com.etesync.syncadapter.journalmanager;
|
||||
|
||||
import com.etesync.syncadapter.App;
|
||||
import com.etesync.syncadapter.GsonHelper;
|
||||
|
||||
import org.apache.commons.codec.Charsets;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
@ -7,9 +10,6 @@ import java.io.IOException;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import com.etesync.syncadapter.App;
|
||||
import com.etesync.syncadapter.GsonHelper;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
@ -19,8 +19,6 @@ import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.Response;
|
||||
|
||||
import static com.etesync.syncadapter.journalmanager.Crypto.hmac;
|
||||
|
||||
abstract class BaseManager {
|
||||
final static protected MediaType JSON = MediaType.parse("application/json; charset=utf-8");
|
||||
|
||||
@ -77,12 +75,14 @@ abstract class BaseManager {
|
||||
|
||||
public String getContent(String keyBase64) {
|
||||
// FIXME: probably cache encryption object
|
||||
return new String(new Crypto.Cipher().decrypt(keyBase64, content), Charsets.UTF_8);
|
||||
Crypto.Cipher cipher = new Crypto.Cipher(keyBase64, null);
|
||||
return new String(cipher.decrypt(content), Charsets.UTF_8);
|
||||
}
|
||||
|
||||
void setContent(String keyBase64, String content) {
|
||||
// FIXME: probably cache encryption object
|
||||
this.content = new Crypto.Cipher().encrypt(keyBase64, content.getBytes(Charsets.UTF_8));
|
||||
Crypto.Cipher cipher = new Crypto.Cipher(keyBase64, null);
|
||||
this.content = cipher.encrypt(content.getBytes(Charsets.UTF_8));
|
||||
}
|
||||
|
||||
byte[] calculateHmac(String keyBase64, String uuid) {
|
||||
@ -99,7 +99,9 @@ abstract class BaseManager {
|
||||
return "DEADBEEFDEADBEEFDEADBEEFDEADBEEF".getBytes();
|
||||
}
|
||||
|
||||
return hmac(keyBase64, hashContent.toByteArray());
|
||||
// FIXME: probably cache encryption object
|
||||
Crypto.Cipher cipher = new Crypto.Cipher(keyBase64, null);
|
||||
return cipher.hmac(hashContent.toByteArray());
|
||||
}
|
||||
|
||||
protected Base() {
|
||||
|
@ -31,32 +31,22 @@ public class Crypto {
|
||||
return Base64.encodeToString(SCrypt.generate(password.getBytes(Charsets.UTF_8), salt.getBytes(Charsets.UTF_8), 16384, 8, 1, keySize), Base64.NO_WRAP);
|
||||
}
|
||||
|
||||
private static byte[] hmac256(byte[] keyByte, byte[] data) {
|
||||
HMac hmac = new HMac(new SHA256Digest());
|
||||
KeyParameter key = new KeyParameter(keyByte);
|
||||
byte[] ret = new byte[hmac.getMacSize()];
|
||||
hmac.init(key);
|
||||
hmac.update(data, 0, data.length);
|
||||
hmac.doFinal(ret, 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static byte[] hmac(String keyBase64, byte[] data) {
|
||||
byte[] derivedKey = hmac256("hmac".getBytes(Charsets.UTF_8), Base64.decode(keyBase64, Base64.NO_WRAP));
|
||||
return hmac256(derivedKey, data);
|
||||
}
|
||||
|
||||
static class Cipher {
|
||||
private SecureRandom _random = null;
|
||||
private final byte[] cipherKey;
|
||||
private final byte[] hmacKey;
|
||||
|
||||
Cipher() {
|
||||
Cipher(String keyBase64, String salt) {
|
||||
byte[] derivedKey; // FIXME use salt = hmac256(salt.getBytes(Charsets.UTF_8), Base64.decode(keyBase64, Base64.NO_WRAP));
|
||||
derivedKey = Base64.decode(keyBase64, Base64.NO_WRAP);
|
||||
cipherKey = hmac256("aes".getBytes(Charsets.UTF_8), derivedKey);
|
||||
hmacKey = hmac256("hmac".getBytes(Charsets.UTF_8), derivedKey);
|
||||
}
|
||||
|
||||
private static final int blockSize = 16; // AES's block size in bytes
|
||||
|
||||
private BufferedBlockCipher getCipher(String keyBase64, byte[] iv, boolean encrypt) {
|
||||
byte[] derivedKey = hmac256("aes".getBytes(Charsets.UTF_8), Base64.decode(keyBase64, Base64.NO_WRAP));
|
||||
KeyParameter key = new KeyParameter(derivedKey);
|
||||
private BufferedBlockCipher getCipher(byte[] iv, boolean encrypt) {
|
||||
KeyParameter key = new KeyParameter(cipherKey);
|
||||
CipherParameters params = new ParametersWithIV(key, iv);
|
||||
|
||||
BlockCipherPadding padding = new PKCS7Padding();
|
||||
@ -68,11 +58,11 @@ public class Crypto {
|
||||
return cipher;
|
||||
}
|
||||
|
||||
byte[] decrypt(String keyBase64, byte[] _data) {
|
||||
byte[] decrypt(byte[] _data) {
|
||||
byte[] iv = Arrays.copyOfRange(_data, 0, blockSize);
|
||||
byte[] data = Arrays.copyOfRange(_data, blockSize, _data.length);
|
||||
|
||||
BufferedBlockCipher cipher = getCipher(keyBase64, iv, false);
|
||||
BufferedBlockCipher cipher = getCipher(iv, false);
|
||||
|
||||
byte[] buf = new byte[cipher.getOutputSize(data.length)];
|
||||
int len = cipher.processBytes(data, 0, data.length, buf, 0);
|
||||
@ -91,11 +81,11 @@ public class Crypto {
|
||||
return out;
|
||||
}
|
||||
|
||||
byte[] encrypt(String keyBase64, byte[] data) {
|
||||
byte[] encrypt(byte[] data) {
|
||||
byte[] iv = new byte[blockSize];
|
||||
getRandom().nextBytes(iv);
|
||||
|
||||
BufferedBlockCipher cipher = getCipher(keyBase64, iv, true);
|
||||
BufferedBlockCipher cipher = getCipher(iv, true);
|
||||
|
||||
byte[] buf = new byte[cipher.getOutputSize(data.length) + blockSize];
|
||||
System.arraycopy(iv, 0, buf, 0, iv.length);
|
||||
@ -111,12 +101,26 @@ public class Crypto {
|
||||
return buf;
|
||||
}
|
||||
|
||||
byte[] hmac(byte[] data) {
|
||||
return hmac256(hmacKey, data);
|
||||
}
|
||||
|
||||
private SecureRandom getRandom() {
|
||||
if (_random == null) {
|
||||
_random = new SecureRandom();
|
||||
}
|
||||
return _random;
|
||||
}
|
||||
|
||||
private static byte[] hmac256(byte[] keyByte, byte[] data) {
|
||||
HMac hmac = new HMac(new SHA256Digest());
|
||||
KeyParameter key = new KeyParameter(keyByte);
|
||||
byte[] ret = new byte[hmac.getMacSize()];
|
||||
hmac.init(key);
|
||||
hmac.update(data, 0, data.length);
|
||||
hmac.doFinal(ret, 0);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
static String sha256(String base) {
|
||||
|
Loading…
Reference in New Issue
Block a user