【发布时间】:2020-04-18 19:03:03
【问题描述】:
我有一些我想在 Dart 中复制的 java 代码(类可以在 here 找到)
/**
* Encrypt object with password
* @param data Object to be encrypted
* @param secret Password to use for encryption
* @return Encrypted version of object
*/
public static EncryptedBytes encrypt(String data, SecretKey secret) throws InvalidKeyException {
try {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secret);
// properly encode the complete ciphertext
//logEncrypt(password, object);
byte[] encodedData = cipher.doFinal(Base64.getEncoder().encode(data.getBytes(Charset.forName("UTF-8"))));
byte[] params = cipher.getParameters().getEncoded();
String paramAlgorithm = cipher.getParameters().getAlgorithm();
return new EncryptedBytes(encodedData, params, paramAlgorithm);
} catch (NoSuchAlgorithmException | IllegalBlockSizeException | NoSuchPaddingException | BadPaddingException | IOException e) {
e.printStackTrace();
}
return null;
}
/**
* Decrypt data with secret
* @param encryptedBytes Object to be decrypted
* @param secret Password to use for decryption
* @return Decrypted version of object
*/
public static String decrypt(EncryptedBytes encryptedBytes, @NonNull SecretKey secret) throws InvalidKeyException {
try {
// get parameter object for password-based encryption
AlgorithmParameters algParams = AlgorithmParameters.getInstance(encryptedBytes.getParamAlgorithm());
// initialize with parameter encoding from above
algParams.init(encryptedBytes.getParams());
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, secret, algParams);
return new String(Base64.getDecoder().decode(cipher.doFinal(encryptedBytes.getData())), Charset.forName("UTF-8"));
} catch (NoSuchAlgorithmException | NoSuchPaddingException | BadPaddingException | IllegalBlockSizeException | IOException | InvalidAlgorithmParameterException e) {
e.printStackTrace();
}
return null;
}
EncryptedBytes 类只是一个数据持有者
@RequiredArgsConstructor
@Getter
public class EncryptedBytes {
private final byte[] data;
private final byte[] params;
private final String paramAlgorithm;
}
我现在在 Dart 中使用的是 PointyCastle 并且已经接近了(虽然没有测试过)
static EncryptedBytes encrypt(String data, KeyParameter keyParameter) {
final AESFastEngine aes = AESFastEngine()..init(false, keyParameter); // false=decrypt
Uint8List encryptedData = aes.process(utf8.encode(data)); // Needs to convert to UTF8 then Base64 and finally be encrypted
Uint8List params;
String algorithm = aes.algorithmName;
return EncryptedBytes(encryptedData, params, algorithm);
}
static String decrypt(EncryptedBytes data, KeyParameter keyParameter) {
final AESFastEngine aes = AESFastEngine()..init(true, keyParameter); // true=encrypt
String encryptedData = utf8.decode(aes.process(data.data)); // Needs to be decrypted, then decoded from Base64 and finally UTF8
return encryptedData;
}
我不完全确定在 Dart 中我可以使用什么来获得与上面的 java 代码等效的代码。 Base64返回一个字符串进行编码,需要一个字符串进行解码,而aes.process()需要并返回Uint8List
【问题讨论】:
-
为什么java代码base64在加密之前对字节进行编码。这没有多大意义。密码需要一个字节数组,这是您在 base 64 步骤之前所拥有的。在这一步之后,你会得到一个字符串,这不是密码所需要的。
-
您从哪里获得 Java 代码中的 IV?
-
你碰巧知道Java实现是如何对这里的参数进行编码的吗?
getParameters().getEncoded()是否在 ASN.1 中? -
@RichardHeap 我相信是this 我尽力找到代码的去向。希望这能回答您的问题。
标签: flutter encryption dart aes pointycastle