我需要解密Flutter移动应用程序中的AES(PKCS#7)编码字符串。
字符串从QR码中获取,QR码由Java应用程序生成,包含AES编码字符串。
Java编码:
import java.security.Security;
import java.nio.charset.StandardCharsets;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
public class MyClass {
public static void main(String[] args) throws Exception {
String toEncode = "firstname.lastname@mycompany.com;12";
String encoded = pleaseEncodeMe(toEncode);
System.out.println(encoded);
}
private static String pleaseEncodeMe(String plainText) throws Exception {
Security.addProvider(new BouncyCastleProvider());
final String encryptionAlgorithm = "AES/CBC/PKCS7PADDING";
final String encryptionKey = "WHatAnAWEsoMeKey";
final SecretKeySpec keySpecification = new SecretKeySpec(encryptionKey.getBytes(StandardCharsets.UTF_8), encryptionAlgorithm);
final Cipher cipher = Cipher.getInstance(encryptionAlgorithm, "BC");
cipher.init(Cipher.ENCRYPT_MODE, keySpecification);
final byte[] encryptedBytes = cipher.doFinal(plainText.getBytes());
return Base64.encodeBase64URLSafeString(encryptedBytes);
}
}
输出:AIRTEuNmSuQtYuysv93w3w83kJJ6sg7kaU7XzA8xrAjOp-lKYPp1brtDAPbhSJmT
Dart解码:
void main() {
print(decodeMeOrDie("AIRTEuNmSuQtYuysv93w3w83kJJ6sg7kaU7XzA8xrAjOp-lKYPp1brtDAPbhSJmT"));
}
String decodeMeOrDie(String encryptedString) {
final key = Key.fromUtf8("WHatAnAWEsoMeKey");
final iv = IV.fromLength(16);
final encrypter = Encrypter(AES(key, mode: AESMode.cbc, padding: "PKCS7"));
return encrypter.decrypt64(encryptedString, iv: iv);
}
输出:Y��=X�Rȑ �"Qme@mycompany.com;12
您可以看到只有字符串的一部分被解码。
2条答案
按热度按时间sqyvllje1#
1)对于解密,需要用于加密的IV。
2)出于安全原因,必须为每次加密随机生成新的IV,使得没有IV被同一密钥here使用多于一次。
因此,IV必须从加密端传递到解密端,这不会自动发生,但必须实现。
这个数据被传输到解密端,在Base64解码后将两部分分开。在AES-CBC的情况下,IV是16个字节长,所以前16个字节代表IV,其余的代表密文。IV不需要加密,因为它不是秘密的。
具体到您的情况,这意味着您必须在Java端连接IV和密文,并对结果进行Base64编码。在Dart端,您必须首先进行Base64解码,然后IV和密文这两部分可以分离并用于以下解密。
Cipher
-示例隐式生成(如示例中所示)或通过SecureRandom显式生成(如通过here)。两种方法都在here中讨论。如果IV是隐式生成的(通过Cipher
-示例),则必须通过Cipher
-示例确定此IV,因为稍后需要解密:如果IV是显式确定的(例如使用
SecureRandom
),它必须传递给Cipher
-示例,以便在运行加密时使用它。4c8rllxm2#
如果它能帮助某些人,下面是我在dart中得到的代码(它使用
encrypt
包):