【发布时间】:2022-08-08 19:56:45
【问题描述】:
我正在尝试在 Flutter 中实现加密,我使用 java 作为后端和移动应用程序的 dart。我从这个Encryption in Java and Decryption in Flutter (AES-256) 中获取了代码 但它只在 Flutter 中提供解密,我想在 Flutter 中实现加密,以便 Java 代码可以解密它。
你能帮我提供 Flutter 中的加密代码吗?
这是用于加密和解密的java代码。
public class EncryptionService {
public String encrypt(String item) throws Exception {
byte[] ivBytes;
String password = \"Hello\";
/* you can give whatever you want for password. This is for testing purpose */
SecureRandom random = new SecureRandom();
byte bytes[] = new byte[20];
random.nextBytes(bytes);
byte[] saltBytes = bytes;
// Derive the key
SecretKeyFactory factory = SecretKeyFactory.getInstance(\"PBKDF2WithHmacSHA1\");
PBEKeySpec spec = new PBEKeySpec(password.toCharArray(), saltBytes, 65556, 256);
SecretKey secretKey = factory.generateSecret(spec);
SecretKeySpec secret = new SecretKeySpec(secretKey.getEncoded(), \"AES\");
System.out.println(\"saltBytes : \" + saltBytes);
// encrypting the word
Cipher cipher = Cipher.getInstance(\"AES/CBC/PKCS5Padding\");
cipher.init(Cipher.ENCRYPT_MODE, secret);
AlgorithmParameters params = cipher.getParameters();
ivBytes = params.getParameterSpec(IvParameterSpec.class).getIV();
System.out.println(\"ivBytes : \" + ivBytes);
byte[] encryptedTextBytes = cipher.doFinal(item.getBytes(\"UTF-8\"));
// prepend salt and vi
byte[] buffer = new byte[saltBytes.length + ivBytes.length + encryptedTextBytes.length];
System.arraycopy(saltBytes, 0, buffer, 0, saltBytes.length);
System.arraycopy(ivBytes, 0, buffer, saltBytes.length, ivBytes.length);
System.arraycopy(encryptedTextBytes, 0, buffer, saltBytes.length + ivBytes.length, encryptedTextBytes.length);
return new Base64().encodeToString(buffer);
}
public String decrypt(String encryptedText) throws Exception {
String password = \"Hello\";
Cipher cipher = Cipher.getInstance(\"AES/CBC/PKCS5Padding\");
// strip off the salt and iv
ByteBuffer buffer = ByteBuffer.wrap(new Base64().decode(encryptedText));
byte[] saltBytes = new byte[20];
buffer.get(saltBytes, 0, saltBytes.length);
byte[] ivBytes1 = new byte[cipher.getBlockSize()];
buffer.get(ivBytes1, 0, ivBytes1.length);
byte[] encryptedTextBytes = new byte[buffer.capacity() - saltBytes.length - ivBytes1.length];
buffer.get(encryptedTextBytes);
// Deriving the key
SecretKeyFactory factory = SecretKeyFactory.getInstance(\"PBKDF2WithHmacSHA1\");
PBEKeySpec spec = new PBEKeySpec(password.toCharArray(), saltBytes, 65556, 256);
SecretKey secretKey = factory.generateSecret(spec);
SecretKeySpec secret = new SecretKeySpec(secretKey.getEncoded(), \"AES\");
cipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(ivBytes1));
byte[] decryptedTextBytes = null;
try {
decryptedTextBytes = cipher.doFinal(encryptedTextBytes);
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
}
return new String(decryptedTextBytes);
}
}
用于解密的 Dart 实现是这样的
class EncryptionHelper {
static String decrypt(
String ciphertext,
) {
Uint8List ciphertextlist = base64.decode(ciphertext);
var salt = ciphertextlist.sublist(0, 20);
var iv = ciphertextlist.sublist(20, 20 + 16);
var encrypted = ciphertextlist.sublist(20 + 16);
Uint8List key = generateKey(\"Hello\", salt);
CBCBlockCipher cipher = new CBCBlockCipher(new AESFastEngine());
ParametersWithIV<KeyParameter> params =
new ParametersWithIV<KeyParameter>(new KeyParameter(key), iv);
PaddedBlockCipherParameters<ParametersWithIV<KeyParameter>, Null>
paddingParams =
new PaddedBlockCipherParameters<ParametersWithIV<KeyParameter>, Null>(
params, null);
PaddedBlockCipherImpl paddingCipher =
new PaddedBlockCipherImpl(new PKCS7Padding(), cipher);
paddingCipher.init(false, paddingParams);
var val = paddingCipher.process(encrypted);
return new String.fromCharCodes(val);
}
static Uint8List generateKey(String passphrase, Uint8List salt) {
Uint8List passphraseInt8List = Uint8List.fromList(passphrase.codeUnits);
KeyDerivator derivator =
PBKDF2KeyDerivator(HMac(SHA1Digest(), 64)); // 64 byte block size
Pbkdf2Parameters params =
Pbkdf2Parameters(salt, 65556, 32); // 32 byte key size
derivator.init(params);
return derivator.process(passphraseInt8List);
}
}
-
由于这是关于使用 Flutter 进行加密的,因此您应该发布最新的 Flutter 代码加密.目前您只发布了解密代码。
-
@Topaco 我不知道如何编写加密代码。我只是在网上复制了代码。
-
你不会\'reverse\'解密吗?以同样的方式导出密钥,在
paddingCipher.init()中将 false 翻转为 true,然后按顺序组装 salt、iv 和 ct(考虑使用BytesBuilder),最后对结果进行 base64 编码。复制 Java 代码对您有帮助,因为您可以在执行这些步骤时检查中间结果。 (当然你需要坚持使用固定盐。) -
作为故障排除的起点,请使用发布的解密代码和/或 PointyCastle 示例发布加密代码的初始版本。
标签: java flutter dart encryption pointycastle