Java aes加密C#解密的取巧方法

简介:

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


Java代码:

/** 
	 * 加密 
	 *  
	 * @param content 需要加密的内容 
	 * @param password  加密密钥
	 * @return 
	 */  
	public static String encrypt(String content, String password) {  
        try {            
            //如下代码用于根据原始的password生成加密的key,这段代码C#是没有对应的实现的
            KeyGenerator kgen = KeyGenerator.getInstance("AES"); 
            java.security.SecureRandom random = 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 (Exception e) {  
            Logger.error(e,"AES加密异常");
        }  
        return null;
	} 

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

1)将Java中key的处理代码抽取出来,写成一个简单的工具类,类名为TestGenAESByteKey。

      TestGenAESByteKey将原始的password转换为AES加密需要的字节,然后Base64编码,得到字符串

2)将以上步骤得到的字符串通过人工的方式拷贝到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{

	/**
	 * @param args
	 * @throws UnsupportedEncodingException 
	 * @throws NoSuchAlgorithmException 
	 */
	public static void main(String[] args) throws UnsupportedEncodingException, NoSuchAlgorithmException {
	    KeyGenerator kgen = KeyGenerator.getInstance("AES"); 
        java.security.SecureRandom random = 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,否则解密出来后结尾可能有乱码




相关文章
|
17天前
|
Linux 数据安全/隐私保护 Windows
aes加密在linux下会生成随机key的解决办法
aes加密在linux下会生成随机key的解决办法
11 2
|
Java 数据安全/隐私保护
Java实现最电话号码的简单加密源码
Java实现最电话号码的简单加密源码
15 0
|
8天前
|
Java
Java中ReentrantLock中tryLock()方法加锁分析
Java中ReentrantLock中tryLock()方法加锁分析
10 0
|
28天前
|
Java
java中日期处理的一些工具方法
java中日期处理的一些工具方法
17 1
|
6天前
|
Java Shell
Java 21颠覆传统:未命名类与实例Main方法的编码变革
Java 21颠覆传统:未命名类与实例Main方法的编码变革
10 0
|
8天前
|
安全 Java
append在Java中是哪个类下的方法
append在Java中是哪个类下的方法
21 9
|
16天前
|
Java
Java通过反射获取类调用方法
Java通过反射获取类调用方法
18 0
|
27天前
|
Java
java面向对象高级分层实例_测试类(main方法所在的类)
java面向对象高级分层实例_测试类(main方法所在的类)
9 1
|
27天前
|
Java API Maven
email api java编辑方法?一文教你学会配置步骤
在Java开发中,Email API是简化邮件功能的关键工具。本文指导如何配置和使用Email API Java:首先,在项目中添加javax.mail-api和javax.mail依赖;接着,配置SMTP服务器和端口;然后,创建邮件,设定收件人、发件人、主题和正文;最后,使用Transport.send()发送邮件。借助Email API Java,可为应用添加高效邮件功能。
|
27天前
|
Java
【Java】重写compareTo()方法给对象数组排序
【Java】重写compareTo()方法给对象数组排序
10 0