C#和JAVA AES加密解密遇到的问题,发现Java的AES加密出来的结果跟C#的AES加密出来的结果不一致

南宫萧尘 2018-02-27 02:54:14
问题卡了几天了,希望懂java和C#双语言的劳烦帮忙解决一下,或者之前对结果java和C#的AES加密的童鞋帮忙给些提示,不胜感激.

先上java的加解密方法:

package com.uns.unspay.common;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class AESEncrypt {
private static String hexStr = "0123456789ABCDEF";
private static final Logger log = LoggerFactory.getLogger(AESEncrypt.class);
/**
* 加密
*
* @param content
* 需要加密的内容
* @return
*/
public static String encrypt(String content, String privateKey) {
try {
KeyGenerator kgen = KeyGenerator.getInstance("AES");
SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
secureRandom.setSeed(privateKey.getBytes());

kgen.init(128, secureRandom);
SecretKey secretKey = kgen.generateKey();
byte[] enCodeFormat = secretKey.getEncoded();
SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
Cipher cipher = Cipher.getInstance("AES");// 创建密码器
byte[] byteContent = content.getBytes("utf-8");
cipher.init(Cipher.ENCRYPT_MODE, key);// 初始化
byte[] result = cipher.doFinal(byteContent);
String strResult = BinaryToHexString(result);
return strResult; // 加密
} catch (NoSuchAlgorithmException e) {
log.error("Invalid Algorith.");
// e.printStackTrace();
} catch (NoSuchPaddingException e) {
log.error(e.getMessage(), e);
} catch (InvalidKeyException e) {
log.error(e.getMessage(), e);
} catch (UnsupportedEncodingException e) {
log.error(e.getMessage(), e);
} catch (IllegalBlockSizeException e) {
log.error(e.getMessage(), e);
} catch (BadPaddingException e) {
log.error(e.getMessage(), e);
}
return null;
}
/**
*
* @param bytes
* @return 将二进制转换为十六进制字符输出
*/
public static String BinaryToHexString(byte[] bytes) {
StringBuilder result = new StringBuilder();
StringBuilder hex = new StringBuilder();
for (int i = 0; i < bytes.length; i++) {
hex.delete(0, hex.length());
// 字节高4位
hex.append(String.valueOf(hexStr.charAt((bytes[i] & 0xF0) >> 4)));
// 字节低4位
hex.append(String.valueOf(hexStr.charAt(bytes[i] & 0x0F)));
result.append(hex);
}
return result.toString();
}
}

再上C#的加密方法
#region AES加解密
/// <summary>
///AES加密(加密步骤)
///1,加密字符串得到2进制数组;
///2,将2禁止数组转为16进制;
///3,进行base64编码
/// </summary>
/// <param name="toEncrypt">要加密的字符串</param>
/// <param name="key">密钥</param>
public static String AESEncrypt(String toEncrypt, String key)
{
Byte[] _Key = Encoding.ASCII.GetBytes(key);
Byte[] _Source = Encoding.UTF8.GetBytes(toEncrypt);
Aes aes = Aes.Create("AES");
aes.Mode = CipherMode.ECB;
aes.Padding = PaddingMode.PKCS7;
aes.Key = _Key;
ICryptoTransform cTransform = aes.CreateEncryptor();
Byte[] cryptData = cTransform.TransformFinalBlock(_Source, 0, _Source.Length);
String HexCryptString = Hex_2To16(cryptData);
Byte[] HexCryptData = Encoding.UTF8.GetBytes(HexCryptString);
String CryptString = Convert.ToBase64String(HexCryptData);
return CryptString;
}
/// <summary>
/// 2进制转16进制
/// </summary>
static String Hex_2To16(Byte[] bytes)
{
String hexString = String.Empty;
Int32 iLength = 65535;
if (bytes != null)
{
StringBuilder strB = new StringBuilder();

if (bytes.Length < iLength)
{
iLength = bytes.Length;
}

for (int i = 0; i < iLength; i++)
{
strB.Append(bytes[i].ToString("X2"));
}
hexString = strB.ToString();
}
return hexString;
}

假如待加密的字符串是:6226620620140212|张三|310101199001021212
密码:1234567890abcdef
那么java的加密结果是:2F04A64A3F452FE73C2B78185DBFFB0768C45D36CDA1113BE98AC1DDE9B97A1F48802DFBD8D56031F322D2AAB637FFE7
C#的加密结果是:
Q0I4ODZGNJE5NJRFRJJGRJM0RDCWNDK4MJIXRTZDNTC1NZAYRTE1NDLGRDDGNUVBNDGXRTQ2QJQ1OEUYNDG0MJVFN0Q2MJYZMZG5NJGYNTVGMUIXNKEZN0I5NDDGM0QY
发现两者不一致,特此请教各位,希望能得到加的解惑.
...全文
33281 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
kampoo 2018-03-04
  • 打赏
  • 举报
回复
默认加密方式得到的代码是不一样,请参考加解密算法的异构系统的交互问题: 3DES加密算法的Android-Java客户端与MVC-C#服务端的加解密问题
xuzuning 2018-02-27
  • 打赏
  • 举报
回复
网上有 Java、C#、php、JavaScript 兼容的 AES 代码,随便找一下就有
南宫萧尘 2018-02-27
  • 打赏
  • 举报
回复
问题已解决,参考此文章:http://www.cnblogs.com/cainiaoji/articles/6676500.html#3911417
  • 打赏
  • 举报
回复
而且net下根本没这块,我刚尝试用BouncyCastle来做,结果无效,每次结果不一样,跟java下的不一样
            var sr = SecureRandom.GetInstance("SHA1PRNG");
            sr.SetSeed(Encoding.GetEncoding("gbk").GetBytes("1234567890abcdef"));
            //RsaKeyPairGenerator
            CipherKeyGenerator keyGen = new CipherKeyGenerator();
            keyGen.Init(new KeyGenerationParameters(sr, 128));
            var keys = keyGen.GenerateKey();
  • 打赏
  • 举报
回复
而且java用了SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");而你是直接对私钥getbytes,这个肯定是不一样的,主要坑就在这块
大鱼> 2018-02-27
  • 打赏
  • 举报
回复
加密算法得到结果不会因为语言而有差异,你应该是哪步错了,或者加密解密算法有稍微出入
  • 打赏
  • 举报
回复
java下是BinaryToHexString,将二进制转成16进制字符串 C#下是Hex_2To16之后再Convert.ToBase64String,比java多了一步

110,533

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

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

试试用AI创作助手写篇文章吧