Aes使用Java加密C#解密

项目开发过程中遇到一个棘手的问题:A系统使用java开发,通过AES加密数据,B系统使用C#开发,需要从A系统获取数据,但在AES解密的时候遇到麻烦。Java的代码和C#的代码无法互通。

Java代码:

   /**
    *加密
    *
    *@paramcontent需要加密的内容
    *@parampassword加密密钥
    *@return
    */
    public static String encrypt(String content,String password){
    try{
    //如下代码用于根据原始的password生成加密的key,这段代码C#是没有对应的实现的
    KeyGenerator kgen=KeyGenerator.getInstance("AES");
    java.security.SecureRandomrandom=java.security.SecureRandom.getInstance("SHA1PRNG");
    random.setSeed(password.getBytes());
    kgen.init(128,random);
    SecretKey secretKey=kgen.generateKey();
    byte[] enCodeFormat=secretKey.getEncoded();

    //如下代码是标准的AES加密处理,C#可以实现
    SecretKeySpec key=new SecretKeySpec(enCodeFormat,"AES");
    Cipher cipher=Cipher.getInstance("AES");
    byte[] byteContent=content.getBytes("utf-8");
    cipher.init(Cipher.ENCRYPT_MODE,key);
    return Codec.encodeBASE64(cipher.doFinal(byteContent));
    }catch(Exceptione){
    Logger.error(e,"AES加密异常");
    }
    return null;
    }

网上找了一些资料,没有找到满意的解决方案,于是尝试了一种取巧的方法,具体实现如下:

  1. 将Java中key的处理代码抽取出来,写成一个简单的工具类,类名为TestGenAESByteKey。
  2. TestGenAESByteKey将原始的password转换为AES加密需要的字节,然后Base64编码,得到字符串
  3. 将以上步骤得到的字符串通过人工的方式拷贝到C#的代码中,作为秘钥解密

具体代码如下:

    //TestGenAESByteKey(Java语言)
    package api;
    import java.io.UnsupportedEncodingException;
    import java.security.NoSuchAlgorithmException;
    import javax.crypto.KeyGenerator;
    import javax.crypto.SecretKey;
    import sun.misc.BASE64Encoder;
    public class TestGenAESByteKey{
    /**
    *@paramargs
    *@throwsUnsupportedEncodingException
    *@throwsNoSuchAlgorithmException
    */
    public static void main(String[]args)throws UnsupportedEncodingException,NoSuchAlgorithmException{
    KeyGenerator kgen=KeyGenerator.getInstance("AES");
    java.security.SecureRandomrandom=java.security.SecureRandom.getInstance("SHA1PRNG");
    random.setSeed(args[0].getBytes());
    kgen.init(128,random);
    SecretKey secretKey=kgen.generateKey();
    byte[] enCodeFormat=secretKey.getEncoded();
    BASE64Encoder coder=new BASE64Encoder();
    System.out.println(coder.encode(enCodeFormat));
    }
    } 

C#的解密代码:

public static string decrypt(string toDecrypt,string key)
       {
           byte[] keyArray = Convert.FromBase64String(key); //将TestGenAESByteKey类输出的字符串转为byte数组
           byte[] toEncryptArray = Convert.FromBase64String(toDecrypt);
           RijndaelManaged rDel = new RijndaelManaged();
           rDel.Key = keyArray;
           rDel.Mode = CipherMode.ECB;        //必须设置为ECB
           rDel.Padding = PaddingMode.PKCS7;  //必须设置为PKCS7
           ICryptoTransform cTransform = rDel.CreateDecryptor();
           byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
           return UTF8Encoding.UTF8.GetString(resultArray);
       }

例如:原始密码为123456,经过TestGenAESByteKey处理后,输出a7SDfrdDKRBe5FaN2n3Gfg==

将a7SDfrdDKRBe5FaN2n3Gfg==作为C#函数decrypt的key参数的值传进去,就可以正常解码了

需要注意几点:
1. C#默认运算模式为CBC,java默认为ECB,因此要将C#的加密方式改为ECB
2. C#的Padding方式要设置为PaddingMode.PKCS7,否则解密出来后结尾可能有乱码

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值