Java解密错误:数据未对齐块大小
我正在尝试加密我的 Android 应用程序和 PHP Web 服务之间的数据。
我在该网站中找到了下一段代码: http://schneimi.wordpress.com/2008/11/25/aes-128bit-encryption- Between-java-and-php/
但是当我尝试解密时我得到标题“数据未块大小对齐”的例外
这是我的MCrypt类中的方法
public String encrypt(String text) throws Exception
{
if(text == null || text.length() == 0)
throw new Exception("Empty string");
Cipher cipher;
byte[] encrypted = null;
try {
cipher = Cipher.getInstance("AES/CBC/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec);
encrypted = cipher.doFinal(padString(text).getBytes());
} catch (Exception e)
{
throw new Exception("[encrypt] " + e.getMessage());
}
return new String( encrypted );
}
public String decrypt(String code) throws Exception
{
if(code == null || code.length() == 0)
throw new Exception("Empty string");
Cipher cipher;
byte[] decrypted = null;
try {
cipher = Cipher.getInstance("AES/CBC/NoPadding");
cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec);
decrypted = cipher.doFinal(hexToBytes(code));
} catch (Exception e)
{
throw new Exception("[decrypt] " + e.getMessage());
}
return new String( decrypted );
}
private static byte[] hexToBytes(String hex) {
String HEXINDEX = "0123456789abcdef";
int l = hex.length() / 2;
byte data[] = new byte[l];
int j = 0;
for (int i = 0; i < l; i++) {
char c = hex.charAt(j++);
int n, b;
n = HEXINDEX.indexOf(c);
b = (n & 0xf) << 4;
c = hex.charAt(j++);
n = HEXINDEX.indexOf(c);
b += (n & 0xf);
data[i] = (byte) b;
}
return data;
}
private static String padString(String source)
{
char paddingChar = ' ';
int size = 16;
int x = source.length() % size;
int padLength = size - x;
for (int i = 0; i < padLength; i++)
{
source += paddingChar;
}
return source;
}
这就是我在活动中使用它来测试的方式:
String encrypted = mcrypt.encrypt(jsonUser.toString());
String decrypted = mcrypt.decrypt(encrypted);
加密方法工作正常,但是第二个抛出异常。
I'm trying to encrypt data between my android application and a PHP webservice.
I found the next piece of code in this website: http://schneimi.wordpress.com/2008/11/25/aes-128bit-encryption-between-java-and-php/
But when I try to decrypt I get the Exception of the title "data not block size aligned"
This are the method in my MCrypt class
public String encrypt(String text) throws Exception
{
if(text == null || text.length() == 0)
throw new Exception("Empty string");
Cipher cipher;
byte[] encrypted = null;
try {
cipher = Cipher.getInstance("AES/CBC/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec);
encrypted = cipher.doFinal(padString(text).getBytes());
} catch (Exception e)
{
throw new Exception("[encrypt] " + e.getMessage());
}
return new String( encrypted );
}
public String decrypt(String code) throws Exception
{
if(code == null || code.length() == 0)
throw new Exception("Empty string");
Cipher cipher;
byte[] decrypted = null;
try {
cipher = Cipher.getInstance("AES/CBC/NoPadding");
cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec);
decrypted = cipher.doFinal(hexToBytes(code));
} catch (Exception e)
{
throw new Exception("[decrypt] " + e.getMessage());
}
return new String( decrypted );
}
private static byte[] hexToBytes(String hex) {
String HEXINDEX = "0123456789abcdef";
int l = hex.length() / 2;
byte data[] = new byte[l];
int j = 0;
for (int i = 0; i < l; i++) {
char c = hex.charAt(j++);
int n, b;
n = HEXINDEX.indexOf(c);
b = (n & 0xf) << 4;
c = hex.charAt(j++);
n = HEXINDEX.indexOf(c);
b += (n & 0xf);
data[i] = (byte) b;
}
return data;
}
private static String padString(String source)
{
char paddingChar = ' ';
int size = 16;
int x = source.length() % size;
int padLength = size - x;
for (int i = 0; i < padLength; i++)
{
source += paddingChar;
}
return source;
}
And this is how I'm using it in my activity to test:
String encrypted = mcrypt.encrypt(jsonUser.toString());
String decrypted = mcrypt.decrypt(encrypted);
the encrypt method works fine, but the second throws an exception.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
终于!我成功了!感谢您的所有建议。我想分享代码,以防万一有人像我一样陷入困境:
JAVA
如何使用它 (JAVA)
============ ==========================================
PHP
如何使用它(PHP)
At last! I made it work! Thanks for all your suggestion. I would like to share the code just in case somebody get stuck like me:
JAVA
HOW TO USE IT (JAVA)
====================================================
PHP
HOW TO USE IT (PHP)
我猜您的
keyspec
和ivspec
对于解密无效。我通常将它们转换为PublicKey
和PrivateKey
实例,然后使用私钥进行解密。I'm guessing your
keyspec
andivspec
are not valid for decryption. I've typically transformed them intoPublicKey
andPrivateKey
instances and then use the private key to decrypt.我看了另一个答案的评论。我在尝试使用 php 中的开放 SSL 加密一大块文本时遇到了类似的问题(双方)。我想同样的问题也会出现在 Java 中。
如果您有 1024 位 RSA 密钥,则必须将传入文本拆分为 117 字节块(一个字符是一个字节)并对每个块进行加密(您可以将它们连接在一起)。另一方面,您必须将加密数据分割成 128 字节的块并对每个块进行解密。这应该会为您提供原始消息。
另请注意,http 可能无法友好地处理非 ASCII 加密数据。我在传输之前和之后对其进行 Base64 编码/解码(另外,您还必须担心 Base64 更改的额外 urlencoding,但这很容易)。
我不确定你的 AES 密钥长度,但如果它是 1024 位,则块长度可能是相同的。如果不是,则必须将这些位除以 8 才能找到字节块的长度。不幸的是,我实际上不确定如何让它进来(也许乘以 117/128 ?)
这是一些 php 代码:
I looked at the comments in the other answer. I ran into a similar problem trying to encrypt a large block of text using open SSL in php (on both sides). I imagine the same issue would come up in Java.
If you have a 1024 bit RSA key, you must split the incoming text into 117 byte chunks (a char is a byte) and encrypt each (you can concatenate them together). On the other end, you must split the encrypted data into 128 byte chunks and decrypt each. This should give you your original message.
Also note that http may not play friendly with the non-ASCII encrypted data. I base64 encode/decode it before and after transmission (plus you have to worry about additional urlencoding for the base64 change, but it is easy).
I'm not sure of your AES key length, but if it's 1024 bits the chunk length is probably the same. If it's not, you will have to divide the bits by 8 to find the byte chunk length coming out. I'm actually not sure how to get it coming in, unfortunately (maybe multiply by 117/128 ?)
Here's some php code: