java和c#的AES256加密解密方法
java
CyptoClient.java中程式碼
package ***.security.crypto;
import java.util.Map;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Maps;
import com.zhengtoon.bjtoon.uia.util.HexUtil;
import org.apache.commons.codec.binary.Base64;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class CyptoClient
{
private static final Logger logger = LogManager.getLogger(CyptoClient.class);
public static final String CHARSET = "UTF-8";
public static String encryptWithAES(String info, String aeskey) {
try {
byte[] key = HexUtil.hexStr2ByteArray(aeskey);
byte[] bytes = info.getBytes();
byte[] encrypt = AES256Coder.encrypt(bytes, key);
return HexUtil.byteArray2HexStr(encrypt);
} catch (Exception e) {
logger.error("encrypt執行失敗: " + e.getMessage(), e);
}
return null;
}
public static String decryptWithAES(String info, String aeskey) {
try {
byte[] key = HexUtil.hexStr2ByteArray(aeskey);
byte[] bytes = HexUtil.hexStr2ByteArray(info);
byte[] decrypt = AES256Coder.decrypt(bytes, key);
return new String(decrypt);
} catch (Exception e) {
logger.error("decrypt執行失敗: " + e.getMessage(), e);
}
return null;
}
}
HexUtil .java中程式碼
package ***.security.crypto;
import org.springframework.util.StringUtils;
public class HexUtil {
/**
* 把hex轉陣列
* @param hexString
* @return
*/
public static byte[] hexStr2ByteArray(String hexString) {
if (StringUtils.isEmpty(hexString))
throw new IllegalArgumentException("this hexString must not be empty");
hexString = hexString.toLowerCase();
final byte[] byteArray = new byte[hexString.length() / 2];
int k = 0;
for (int i = 0; i < byteArray.length; i++) {
//因為是16進位制,最多隻會佔用4位,轉換成位元組需要兩個16進位制的字元,高位在先
//將hex 轉換成byte "&" 操作為了防止負數的自動擴充套件
// hex轉換成byte 其實只佔用了4位,然後把高位進行右移四位
// 然後“|”操作 低四位 就能得到 兩個 16進位制數轉換成一個byte.
byte high = (byte) (Character.digit(hexString.charAt(k), 16) & 0xff);
byte low = (byte) (Character.digit(hexString.charAt(k + 1), 16) & 0xff);
byteArray[i] = (byte) (high << 4 | low);
k += 2;
}
return byteArray;
}
public static String byteArray2HexStr(byte[] byteArray) {
if (byteArray == null || byteArray.length < 1) {
throw new IllegalArgumentException("this byteArray must not be null or empty");
}
final StringBuilder hexString = new StringBuilder();
for (int i = 0; i < byteArray.length; i++) {
if ((byteArray[i] & 0xff) < 0x10)// 0~F前面不零
hexString.append("0");
hexString.append(Integer.toHexString(0xFF & byteArray[i]));
}
return hexString.toString().toLowerCase();
}
}
AES256Coder.java中程式碼
package ***.security.crypto;
import com.zhengtoon.bjtoon.uia.support.converter.MessageConverter;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.security.Key;
import java.security.Security;
/**
* ${DESCRIPTION}
*/
public class AES256Coder {
private static final Logger logger = LogManager.getLogger(MessageConverter.class);
public static final String KEY_ALGORITHM = "AES";
public static final String CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding";
public static final Integer KEY_LENGTH = 256;
public static byte[] initkey() throws Exception {
Security.addProvider(new BouncyCastleProvider());
KeyGenerator kg = KeyGenerator.getInstance(KEY_ALGORITHM, "BC");
SecretKey secretKey = kg.generateKey();
return secretKey.getEncoded();
}
public static Key toKey(byte[] key) throws Exception {
SecretKey secretKey = new SecretKeySpec(key, KEY_ALGORITHM);
return secretKey;
}
public static byte[] encrypt(byte[] data, byte[] key) throws Exception {
Key k = toKey(key);
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM, "BC");
cipher.init(Cipher.ENCRYPT_MODE, k);
return cipher.doFinal(data);
}
public static byte[] decrypt(byte[] data, byte[] key) throws Exception {
Key k = toKey(key);
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, k);
return cipher.doFinal(data);
}
}
上面的是java的AES256加密解密方法,引用了很多包,我需要用c#接收加密資料並解析,同時我這邊也要對資料加密傳回去,所以我需要對上面的方法進行修改為c#的方法,下面貼c#的方法,程式碼都簡單放在一個檔案中了,不和java那樣封裝多次
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Security.Cryptography;
using System.IO;
namespace YMS.Command.SecurityHelper
{
public class AES256Provider
{
private AES256Provider()
{
}
/// <summary>
/// AES加密
/// </summary>
/// <param name="encryptStr">明文</param>
/// <param name="key">金鑰</param>
/// 16位金鑰對應128位編碼,24位金鑰對應192位,32對應256位編碼
/// <returns></returns>
public static string Encrypt(string encryptStr, string key)
{
try {
byte[] keyArray = hexStr2ByteArray(key);
byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(encryptStr);
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 byteArray2HexStr(resultArray);
}
catch (Exception ex)
{
}
return null;
}
/// <summary>
/// AES解密
/// </summary>
/// <param name="decryptStr">密文</param>
/// <param name="key">金鑰</param>
/// <returns></returns>
public static string Decrypt(string decryptStr, string key)
{
try
{
byte[] keyArray = hexStr2ByteArray(key);
byte[] toEncryptArray = hexStr2ByteArray(decryptStr);
RijndaelManaged rDel = new RijndaelManaged();
rDel.Key = keyArray;
rDel.Mode = CipherMode.ECB;
rDel.Padding = PaddingMode.PKCS7;
ICryptoTransform cTransform = rDel.CreateDecryptor();
byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
return UTF8Encoding.UTF8.GetString(resultArray);
}
catch (Exception ex)
{
}
return null;
}
public static byte[] hexStr2ByteArray(String hexString)
{
try
{
if (string.IsNullOrEmpty(hexString))
throw new Exception("this hexString must not be empty");
hexString = hexString.ToLower();
byte[] byteArray = new byte[hexString.Length / 2];
int k = 0;
for (int i = 0; i < byteArray.Length; i++)
{
//把hexString中的兩個16進位制數轉化為位元組,一個16進位制數是4位,兩個就是8位即一個位元組
//Substring(k, 2)的作用是從k開始擷取2個數據
byteArray[i]= Convert.ToByte(hexString.Substring(k, 2), 16);
k += 2;
}
return byteArray;
}
catch (Exception ex)
{
}
return null;
}
public static String byteArray2HexStr(byte[] byteArray)
{
try
{
StringBuilder hexString = new StringBuilder();
foreach (byte b in byteArray)
{
//X2表示十六進位制格式(大寫),域寬2位,不足的左邊填0。
hexString.AppendFormat("{0:x2}", b);
}
return hexString.ToString().ToLower();
}
catch (Exception ex)
{
}
return null;
}
}
}
java程式碼是甲方給的工具類,c#是我自己進行修改的,不當之處望指正