c# 中MD5.ComputeHash() aes加密,在Java和golang中的實現

類似移植C#代碼需求,需要加密效果一致。

C#中使用了AesCryptoServiceProvider加密,文檔鏈接 AesCryptoServiceProvider 類
下載裏面代碼在Visul Studio2019中可以針對原加密字符解密;但是在java/go中效果不一樣。
過程中參考的資料網址:
JAVA AES 加密後,結果的長度
MD5.ComputeHash()是怎麼實現的?
Md5加密中 C#和Java得到的加密結果不同

由於不熟悉C#,用VisulStudio運行c#demo都還是找朋友搭建的…
過程中主要問題是:
1、MD5出來的結果和C#中ComputeHash()效果不一致
2、不知道AES 具體用的什麼加密

結果是瞎摸出來的- - 通過對比MD5後的byte[]數組對比是否一致

參數和預期效果

	private static final String pwd = "111111";//需要加密的原字符
	private static final String Key = "11111111111111111";//加密祕鑰17個1
	private static final String Iv = "11111111111111111";//偏移量  17個1
	m4bZ90K+7+xldmbrdNP2TQ==                   //加密結果

byte[]數組比較

// “111111” 的byte[]和md5結果比較
[-106, -25, -110, 24, -106, 94, -73, 44, -110, -91, 73, -35, 90, 51, 1, 18] //byte[]
96e79218965eb72c92a549dd5a330112  //HEX

// KEY的byte[]
[23, 47, 31, 102, 44, 51, 22, -125, -71, 17, 100, 56, -5, 0, -102, 21] //byte[] 17個1

//輸出結果的byte[]
//java
[155 134 217 247 66 190 239 236 101 118 102 235 116 211 246 77]  
//go不知道爲啥不一樣..可能符號. 負數和正的正好255差別...
[-101, -122, -39, -9, 66, -66, -17, -20, 101, 118, 102, -21, 116, -45, -10, 77] 

//結果:
9b86d9f742beefec657666eb74d3f64d //hex
m4bZ90K+7+xldmbrdNP2TQ==	//base64

代碼摘自網絡~~~~

JAVA 代碼

	public static void main(String[] args) {
		try {
			System.out.println(Arrays.toString(getBytes(pwd)));
			System.out.println(Arrays.toString(getBytes(Key)));
			System.out.println(toHexString1(getBytes(pwd)));
			System.out.println(Encrypt(pwd, getBytes(Key), getBytes(Iv)));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	private static byte[] getBytes(String s) throws NoSuchAlgorithmException,
			UnsupportedEncodingException {
		MessageDigest md5 = MessageDigest.getInstance("MD5");
		byte[] sbytes = s.getBytes("utf-8");
		byte[] bytes = md5.digest(sbytes);
		return bytes;
	}
	public static String Encrypt(String sSrc, byte[] key, byte[] iv)
			throws Exception {
		SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
		Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");// "算法/模式/補碼方式"
		IvParameterSpec _iv = new IvParameterSpec(iv);// 使用CBC模式,需要一個向量iv,可增加加密算法的強度
		cipher.init(Cipher.ENCRYPT_MODE, skeySpec, _iv);
		byte[] encrypted = cipher.doFinal(sSrc.getBytes("utf-8"));
		System.out.println(Arrays.toString(encrypted));
		System.out.println("resultHex: " + toHexString1(encrypted));
		// commons-codec或者自帶的base64都行
		// return org.apache.commons.codec.binary.Base64.encodeBase64String(encrypted);
		return new String(java.util.Base64.getEncoder().encode(encrypted));
	}

golang代碼

//隨意命名... 就不整理了...
func main() {
	pwd  := "111111"
	ekey := "11111111111111111"
	eiv := "11111111111111111"
	origData := []byte(pwd) // 待加密的數據
	key := []byte(ekey) // 加密的密鑰
	eivbytes := []byte(eiv) // 加密的密鑰
	no := md5.Sum(origData)
	nokey := md5.Sum(key)
	noiv := md5.Sum(eivbytes)
	uk := make([]byte, 16)
	copy(uk,nokey[:16])
	ui := make([]byte, 16)
	copy(ui,noiv[:16])
	noi := make([]byte, 16)
	copy(noi,no[:16])
	log.Printf("keyv %v",uk)
	log.Printf("keyv2 %v",no)
	encrypted := AesEncryptCBC2(origData, uk,ui)
	log.Printf("resultb %v",encrypted)
	log.Println("密文(hex):", hex.EncodeToString(noi))
	log.Println("密文(hex):", hex.EncodeToString(encrypted))
	log.Println("密文(base64):", base64.StdEncoding.EncodeToString(encrypted))
}

// =================== CBC ======================
func AesEncryptCBC2(origData []byte, key []byte,iv []byte) (encrypted []byte) {
	// 分組祕鑰
	// NewCipher該函數限制了輸入k的長度必須爲16, 24或者32
	block, _ := aes.NewCipher(key)
	blockSize := block.BlockSize()                              // 獲取祕鑰塊的長度
	origData = pkcs5Padding(origData, blockSize)                // 補全碼
	blockMode := cipher.NewCBCEncrypter(block, iv) // 加密模式
	encrypted = make([]byte, len(origData))                     // 創建數組
	blockMode.CryptBlocks(encrypted, origData)                  // 加密
	return encrypted
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章