String plain1= "Test";
byte[] cipher = SplashSecure.getInstance().encrypt2(plain1);
String plain2 = SplashSecure.getInstance().decrypt2(cipher);
plain =Test
解密后plainText2
应该等于plaintext
。但不是。{/ p>
加密/解密方法。
public void initKey(String key) {
String paddedKey = Utils.padString(key);
mKeyspec = new SecretKeySpec(Utils.getBytes(paddedKey), "AES/ECB/NoPadding");
// Utils.getBytes returns "paddedKey.getBytes("CP1252")"
}
public byte[] encrypt2(String data) {
try {
Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, mKeyspec);
String paddedData = Utils.padString(data);
return cipher.doFinal(Utils.getBytes(paddedData));
} catch(InvalidKeyException e) {
e.printStackTrace();
// Series of catch blocks
}
return null;
}
public String decrypt2(byte[] cypherText) {
try {
Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding");
cipher.init(Cipher.DECRYPT_MODE, mKeyspec);
byte[] plainTextBytes = cipher.doFinal(cypherText);
return Utils.getString(plainTextBytes);
// Utils.getString returns "new String(bytes, "CP1252");"
} catch(InvalidKeyException e) {
// Series of catch blocks.
}
return null;
}
编辑:
public static String padString(String source) {
char paddingChar = '\0';
int size = 16;
int padLength = size - source.length() % size;
for (int i = 0; i < padLength; i++) {
source += paddingChar;
}
return source;
}
编辑:
我试图让加密解密在Windows(加密和服务器的其他客户端)和android上运行。 Windows客户端是一个使用Rijndael类(http://svn.openfoundry.org/pcman/2007.06.03/Lite/Rijndael.h)的VC ++应用程序,而android使用http://www.cs.ucdavis.edu/~rogaway/ocb/ocb-java/Rijndael.java Windows客户端已加密数据并将其存储在服务器上。我需要为android构建一个客户端来获取加密数据,解密并显示给用户。
我确定我使用正确的密钥进行解密。
答案 0 :(得分:2)
AES的块大小为128位(即16字节)。它只能 处理此大小的块中的数据,因此即使您告诉它使用NoPadding
它也无法遵守。
这里发生的最可能的事情是,您正在使用的AES实现是在内部填充最多16个字节的四个字节的输入并加密结果。当你解密时,你会得到相同的16个字节,即'T','e','s','t'和12个垃圾字节。
您看到的输出支持:“测试”后跟24个?
符号。我不知道为什么它为每个垃圾字节打印两个?
符号,但我猜这与解释unicode中的垃圾字节有关。您可以通过打印解密的blob的原始字节值来查看正在发生的事情。
简短的回答是'NoPadding'对于分组密码没有意义(或者,如果你打算使用NoPadding,那么你必须自己填充和取消填充内容。)