kan*_*ert 7 java encryption android
我有以下代码.
byte[] input = etInput.getText().toString().getBytes();
byte[] keyBytes = new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17 };
SecretKeySpec key = new SecretKeySpec(keyBytes, "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding", "BC");
// encryption pass
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] cipherText = new byte[cipher.getOutputSize(input.length)];
int ctLength = cipher.update(input, 0, input.length, cipherText, 0);
ctLength += cipher.doFinal(cipherText, ctLength);
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] plainText = new byte[cipher.getOutputSize(ctLength)];
int ptLength = cipher.update(cipherText, 0, ctLength, plainText, 0);
String strLength = new String(cipherText,"US-ASCII");
byte[] byteCiphterText = strLength.getBytes("US-ASCII");
Log.e("Decrypt", Integer.toString(byteCiphterText.length));
etOutput.setText(new String(cipherText,"US-ASCII"));
cipherText = etOutput.getText().toString().getBytes("US-ASCII");
Log.e("Decrypt", Integer.toString(cipherText.length));
ptLength += cipher.doFinal(plainText, ptLength);
Log.e("Decrypt", new String(plainText));
Log.e("Decrypt", Integer.toString(ptLength));
Run Code Online (Sandbox Code Playgroud)
它完美地运作.但是一旦我将它转换为课程.它总是在这一行中遇到错误.
ptLength += cipher.doFinal(plainText, ptLength);
Error:Pad block corrupted
Run Code Online (Sandbox Code Playgroud)
我检查过并且两个代码完全一样.即使转换字符串中传递给字节的值也与上面的代码没有什么不同.知道代码有什么问题吗?
public String Encrypt(String strPlainText) throws Exception, NoSuchProviderException,
NoSuchPaddingException {
byte[] input = strPlainText.getBytes();
byte[] keyBytes = new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17 };
SecretKeySpec key = new SecretKeySpec(keyBytes, "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding", "BC");
// encryption pass
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] cipherText = new byte[cipher.getOutputSize(input.length)];
int ctLength = cipher.update(input, 0, input.length, cipherText, 0);
ctLength += cipher.doFinal(cipherText, ctLength);
return new String(cipherText, "US-ASCII");
}
public String Decrypt(String strCipherText) throws Exception,
NoSuchProviderException, NoSuchPaddingException {
byte[] cipherText = strCipherText.getBytes("US-ASCII");
int ctLength = cipherText.length;
byte[] keyBytes = new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17 };
SecretKeySpec key = new SecretKeySpec(keyBytes, "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding", "BC");
// decryption pass
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] plainText = new byte[cipher.getOutputSize(ctLength)];
int ptLength = cipher.update(cipherText, 0, ctLength, plainText, 0);
ptLength += cipher.doFinal(plainText, ptLength);
return new String(plainText);
}
Run Code Online (Sandbox Code Playgroud)
正如Yann Ramin所说,使用String加密/输出失败。这是二进制数据
如您的第一个示例中那样,使用普通byte []或进行十六进制编码或base64编码的byte []。
// this is a quick example - dont use sun.misc inproduction
// - go for some open source implementation
String encryptedString = new sun.misc.BASE64Encoder.encodeBuffer(encryptedBytes);
Run Code Online (Sandbox Code Playgroud)
该字符串可以安全地传输并映射回字节。
编辑
解决长度问题的最安全方法可能是始终使用流式实现(IMHO):
例
static public byte[] decrypt(Cipher cipher, SecretKey key, byte[]... bytes)
throws GeneralSecurityException, IOException {
cipher.init(Cipher.DECRYPT_MODE, key);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
for (int i = 0; i < bytes.length; i++) {
bos.write(cipher.update(bytes[i]));
}
bos.write(cipher.doFinal());
return bos.toByteArray();
}
Run Code Online (Sandbox Code Playgroud)
您已指定 PKCS7 填充。当存储在 String 对象中时,您的填充是否被保留?您的字符串对象与密码输出的字节是否 1:1 匹配?一般来说,字符串不适合传递二进制数据,例如密码输出。
| 归档时间: |
|
| 查看次数: |
26051 次 |
| 最近记录: |