在項目中遇到這麼一個問題:java
java端須要把一些數據AES加密後傳給C#端,找了好多資料,算是解決了,分享一下:算法
import sun.misc.BASE64Decoder; import sun.misc.BASE64Encoder; import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import java.security.SecureRandom; public class AesEncodeUtil { private final static String transferKey ="qazwsxedcrfv12345"; public static void main(String[] args) throws Exception { String a = aesTransferEncrypt("QAZwsx123!@#$%^&*"); System.out.println(a); System.out.println(aesTransferDncrypt(a)); } /** * 傳輸用加密 * @param content * @return * @throws Exception */ public static String aesTransferEncrypt(String content) throws Exception { return base64Encode(aesEncryptToBytes(content, transferKey)); } /** * 傳輸用解密 * @param content * @return * @throws Exception */ public static String aesTransferDncrypt(String encryptStr) throws Exception { return aesDecryptByBytes(base64Decode(encryptStr), transferKey); } /** * base 64 encode * @param bytes 待編碼的byte[] * @return 編碼後的base 64 code */ private static String base64Encode(byte[] bytes) { return new BASE64Encoder().encode(bytes); } /** * base 64 decode * @param base64Code 待解碼的base 64 code * @return 解碼後的byte[] * @throws Exception */ private static byte[] base64Decode(String base64Code) throws Exception { return new BASE64Decoder().decodeBuffer(base64Code); } /** * AES加密 * @param content 待加密的內容 * @param encryptKey 加密密鑰 * @return 加密後的byte[] * @throws Exception */ private static byte[] aesEncryptToBytes(String content, String encryptKey) throws Exception { KeyGenerator kgen = KeyGenerator.getInstance("AES"); SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG" ); secureRandom.setSeed(encryptKey.getBytes()); kgen.init(128, secureRandom); Cipher cipher = Cipher.getInstance("AES"); cipher.init(Cipher.ENCRYPT_MODE, kgen.generateKey()); return cipher.doFinal(content.getBytes("UTF-8")); } /** * AES解密 * @param encryptBytes 待解密的byte[] * @param decryptKey 解密密鑰 * @return 解密後的String * @throws Exception */ private static String aesDecryptByBytes(byte[] encryptBytes, String decryptKey) throws Exception { KeyGenerator kgen = KeyGenerator.getInstance("AES"); SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG" ); secureRandom.setSeed(decryptKey.getBytes()); kgen.init(128, secureRandom); Cipher cipher = Cipher.getInstance("AES"); cipher.init(Cipher.DECRYPT_MODE,kgen.generateKey()); byte[] decryptBytes = cipher.doFinal(encryptBytes); return new String(decryptBytes,"UTF-8"); } }
java代碼加密/解密運行結果:dom
加密結果:BKscOr7eK4jTO5Hcw5oxqS8HWg2SRhtGfMctz8t/45g=
解密結果:QAZwsx123!@#$%^&*編碼
再看看C#代碼:加密
/// <summary> /// AES加密 (128-ECB加密模式) /// </summary> /// <param name="toEncrypt">內容</param> /// <param name="key">祕鑰</param> /// <returns></returns> public static string AESEncrypt(string toEncrypt, string key) { byte[] keyArray = Convert.FromBase64String(key); byte[] toEncryptArray = Encoding.UTF8.GetBytes(toEncrypt); RijndaelManaged rDel = new RijndaelManaged(); rDel.Key = keyArray; rDel.Mode = CipherMode.ECB; rDel.Padding = PaddingMode.PKCS7; ICryptoTransform cTransform = rDel.CreateEncryptor(); byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length); return Convert.ToBase64String(resultArray, 0, resultArray.Length); } /// <summary> /// AES解密(128-ECB加密模式) /// </summary> /// <param name="toDecrypt">密文</param> /// <param name="key">祕鑰(Base64String)</param> /// <returns></returns> public static string AESDecrypt(string toDecrypt, string key) { try { byte[] keyArray = Convert.FromBase64String(key); //128bit 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(); //用當前的 Key 屬性和初始化向量 (IV) 建立對稱解密器對象 byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length); return Encoding.UTF8.GetString(resultArray); } catch { return null; } }
可是若是直接把 transferKey ="qazwsxedcrfv12345" 和 加密結果:BKscOr7eK4jTO5Hcw5oxqS8HWg2SRhtGfMctz8t/45g=spa
給C#,C#是沒法解密的,由於 rDel.Key = keyArray; 會報錯。code
那麼怎麼辦呢? 其實咱們要把transferKey ="qazwsxedcrfv12345" 處理下,orm
import java.security.NoSuchAlgorithmException;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import sun.misc.BASE64Encoder; 對象
public class t1 {blog
public static void main(String[] args) throws NoSuchAlgorithmException {
String transferKey ="bt龘靐麷鸜鬱nm018讟虋纞idnwtyaTN灩厵麷鸜鬱驪NkkdTnd11_!@$齽齼鼺黸TTASdg212c驫饢籱21_djTdj";
KeyGenerator kgen = KeyGenerator.getInstance("AES");
java.security.SecureRandom random = java.security.SecureRandom.getInstance("SHA1PRNG");
random.setSeed(transferKey.getBytes());
kgen.init(128, random);
SecretKey secretKey = kgen.generateKey();
byte[] enCodeFormat = secretKey.getEncoded();
BASE64Encoder coder = new BASE64Encoder();
System.out.println(coder.encode(enCodeFormat));
}
}
運行結果:0UkIZmHsXb0BUql/L3R6Aw== 纔是C#須要的key
看看C#調用及結果:
以上只是一個簡單的示例。