AES解密后是乱码,但是java解密就正常

weixin_42362748 2018-06-29 11:21:55
public string data = "8D2948A6EB27C9AD4CFACC5EF90ADD5ABADED6422B883FCCB46EDAA573866B566D913455C8018EA8494FE234FFAB83F53A61CC5F3C67EAD40D7C5A5EE3FF3141F5BF223BFEC50A7A862D21C16AE147391C639F433942F4D373F7E3C6A20665B65F3AB3A1380EAE3BB7BAEE45C071226F94A75F133CDA63492622C3144AAAD9168244D9553E5755C952A12F990EC4E92612283A376D9558291F330DE9123046F2EA5166B496E266EBCA96A228C3E724E84D9A74C6499C80BDC4BF23B0735509579D34C03FBD6746B89F0957352A5A38ED16F5307547D072D71C57FAE4CEA073602EC6A7AFA3D1E23D4A59F5381CA9F6C151A99F5D38FE22CBC3C55FC49A697D559035D6B63459D00DA10CFA25CF8026F8477F39FD3D7B7316BE0218183279ABFC";
public string key = "1833ad3ad741456db435163fc5de7e76";

解密代码:
public static string AesDecrypt(string str, string key)
{
if (string.IsNullOrEmpty(str)) return null;
Byte[] toEncryptArray = Convert.FromBase64String(str);
Byte[] keyArray = new byte[32];
keyArray = System.Text.UTF8Encoding.UTF8.GetBytes(key);
System.Security.Cryptography.RijndaelManaged rm = new System.Security.Cryptography.RijndaelManaged
{
Key = keyArray,
Mode = System.Security.Cryptography.CipherMode.ECB,
Padding = System.Security.Cryptography.PaddingMode.Zeros
};

System.Security.Cryptography.ICryptoTransform cTransform = rm.CreateDecryptor();
Byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);

return Encoding.UTF8.GetString(resultArray);
}
...全文
380 点赞 收藏 9
写回复
9 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
weixin_42362748 2018-06-29
NB @xuzuning
回复
xuzuning 2018-06-29
Byte[] toEncryptArray = Convert.FromBase64String(str);
Byte[] keyArray = new byte[32];
keyArray = System.Text.UTF8Encoding.UTF8.GetBytes(key);
应为
Byte[] toEncryptArray = hex2byte(str);
Byte[] keyArray = new byte[32];
keyArray = hex2byte(key);
其中 hex2byte 为自定义方法,可写作
        static byte[] hex2byte(string str)
{
byte[] byteArray = new byte[str.Length / 2];
for (int i = 0, k = 0; i < str.Length; i += 2, k++)
{
byteArray[k] = (byte)Convert.ToInt16(str.Substring(i, 2), 16);
}
return byteArray;
}
            string data = "8D2948A6EB27C9AD4CFACC5EF90ADD5ABADED6422B883FCCB46EDAA573866B566D913455C8018EA8494FE234FFAB83F53A61CC5F3C67EAD40D7C5A5EE3FF3141F5BF223BFEC50A7A862D21C16AE147391C639F433942F4D373F7E3C6A20665B65F3AB3A1380EAE3BB7BAEE45C071226F94A75F133CDA63492622C3144AAAD9168244D9553E5755C952A12F990EC4E92612283A376D9558291F330DE9123046F2EA5166B496E266EBCA96A228C3E724E84D9A74C6499C80BDC4BF23B0735509579D34C03FBD6746B89F0957352A5A38ED16F5307547D072D71C57FAE4CEA073602EC6A7AFA3D1E23D4A59F5381CA9F6C151A99F5D38FE22CBC3C55FC49A697D559035D6B63459D00DA10CFA25CF8026F8477F39FD3D7B7316BE0218183279ABFC";
string key = "1833ad3ad741456db435163fc5de7e76";
Console.WriteLine(AesDecrypt(data,key));
回复
hex2bin(key)
你确认你GetBytes(key)那写法能解密?
回复
weixin_42362748 2018-06-29
java加密解密代码:
package demo.test.util;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

/**
* AES加解密工具
*
* @author lei.sun-1
* @date 2015年12月21日
*/
public class AESUtil {
/**
* 加密
*
* @param key 需要加密的业务类型
* 128|196|256位密钥
* @param data
* 待加密的字符串
* @return 密文
*/
public static String encode(String key, String data) {
try {
SecretKey secretKey = new SecretKeySpec(hex2bin(key), "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
byte[] bytes = cipher.doFinal(data.getBytes());
return bin2hex(bytes);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}

/**
* 加密
*
* @param key
* 128|196|256位密钥
* @param data
* 明文
* @return 密文
*/
public static String encode(String key, String data, String charset) {
try {
SecretKey secretKey = new SecretKeySpec(hex2bin(key), "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
byte[] bytes = cipher.doFinal(data.getBytes(charset));
return bin2hex(bytes);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}

/**
* 解密
*
* @param key
* 128|196|256位密钥
* @param data
* 密文
* @return 明文
*/
public static String decode(String key, String data, String charset) {
try {
SecretKey secretKey = new SecretKeySpec(hex2bin(key), "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, secretKey);
byte[] bytes = cipher.doFinal(hex2bin(data));
return new String(bytes, charset);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}

/**
* 将2进制转换成16进制
*
* @param bin
* 2进制数组
* @return 16进制字符串
*/
private static String bin2hex(byte[] bin) throws Exception {
StringBuffer buf = new StringBuffer();
for (int i = 0; i < bin.length; i++) {
String hex = Integer.toHexString(bin[i] & 0xFF);
if (hex.length() == 1) {
hex = '0' + hex;
}
buf.append(hex.toUpperCase());
}
return buf.toString();
}

/**
* 将16进制转换为2进制
*
* @param hex
* 16进制字符串
* @return 2进制数组
*/
private static byte[] hex2bin(String hex) throws Exception {
if (hex.length() < 1)
return null;
byte[] result = new byte[hex.length() / 2];
for (int i = 0; i < hex.length() / 2; i++) {
int high = Integer.parseInt(hex.substring(i * 2, i * 2 + 1), 16);
int low = Integer.parseInt(hex.substring(i * 2 + 1, i * 2 + 2), 16);
result[i] = (byte) (high * 16 + low);
}
return result;
}

/**
* 随机生成秘钥
*/
public static void getkey() {
try {
KeyGenerator kg = KeyGenerator.getInstance("AES");
kg.init(128);
//要生成多少位,只需要修改这里即可128, 192或256
SecretKey sk = kg.generateKey();
byte[] b = sk.getEncoded();
String s = bin2hex(b);
System.out.println(s);
System.out.println("十六进制密钥长度为"+s.length());
System.out.println("二进制密钥的长度为"+s.length()*4);
}
catch (Exception e) {
e.printStackTrace();

}
}

public static void main(String[] args) {
getkey();
}

}
回复
weixin_42362748 2018-06-29
用java解密后的明文为如下:
{"gid":"a9f95316c3524179b0e895a17b08ccd5","data":{"livecanal_hit_rate_interval":1,"loancanal_hit_sum":1,"livecanal_hit_sum":0,"total_hit_sum":1,"tel":"13520507685","score_total":-1,"loancanal_hit_rate_interval":1},"message":"SUCCESS","moduleId":"100","status":"0"}

但是用c#解密后乱码
回复
weixin_42362748 2018-06-29
public static string AesEncrypt(string encryptStr, string key)
{
byte[] keyArray = UTF8Encoding.UTF8.GetBytes(key);
byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(encryptStr);

RijndaelManaged rDel = new RijndaelManaged();
rDel.Key = keyArray;
rDel.Mode = CipherMode.ECB;
rDel.Padding = PaddingMode.Zeros;

ICryptoTransform cTransform = rDel.CreateEncryptor();
byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);

return Convert.ToBase64String(resultArray, 0, resultArray.Length);
}

加密我用的是如上的代码;
但是和java的加密出的结果不一样;
java的aes加密代码如下:
public static String encode(String key, String data) {
try {
SecretKey secretKey = new SecretKeySpec(hex2bin(key), "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
byte[] bytes = cipher.doFinal(data.getBytes());
return bin2hex(bytes);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
回复
xuzuning 2018-06-29
对于 byte2hex,C# 已经提供了通用方法 BitConverter.ToString,你可根据具体需要在对其结果做些字符串操作
自己写一个也是一样
        public static string Encrypt(string toEncrypt, string key, string iv)
{
byte[] keyArray = UTF8Encoding.UTF8.GetBytes(key);
byte[] ivArray = UTF8Encoding.UTF8.GetBytes(iv);
byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(toEncrypt);

RijndaelManaged rDel = new RijndaelManaged();
rDel.Key = keyArray;
rDel.IV = ivArray;
rDel.Mode = CipherMode.CBC;
rDel.Padding = PaddingMode.Zeros;

ICryptoTransform cTransform = rDel.CreateEncryptor();
byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);

return Convert.ToBase64String(resultArray, 0, resultArray.Length);
}

public static string Decrypt(string toDecrypt, string key, string iv)
{
byte[] keyArray = UTF8Encoding.UTF8.GetBytes(key);
byte[] ivArray = UTF8Encoding.UTF8.GetBytes(iv);
byte[] toEncryptArray = Convert.FromBase64String(toDecrypt);

RijndaelManaged rDel = new RijndaelManaged();
rDel.Key = keyArray;
rDel.IV = ivArray;
rDel.Mode = CipherMode.CBC;
rDel.Padding = PaddingMode.Zeros;

ICryptoTransform cTransform = rDel.CreateDecryptor();
byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);

return UTF8Encoding.UTF8.GetString(resultArray);
}
你好像也是用的这个,只不过你没有考虑编码方式对结果的影响
回复
weixin_42362748 2018-06-29
那加密的方法是怎样的那?和java的算法一样的。@xuzuning
回复
weixin_42362748 2018-06-29
有 byte2hex的代码吗?多谢@xuzuning
回复
相关推荐
发帖
C#
创建于2007-09-28

10.6w+

社区成员

.NET技术 C#
申请成为版主
帖子事件
创建了帖子
2018-06-29 11:21
社区公告

让您成为最强悍的C#开发者