C#, Java, PHP, Python和Javascript幾種語言的AES加密解密實現【多種語言AES/CBC/PKCS5Padding通用加解密資料】

來源:互聯網
上載者:User

http://www.tuicool.com/articles/nERnqe

http://www.cnblogs.com/AloneSword/p/3485912.html【這裡有具體的對稱和非對稱演算法的詳細介紹】

c#裡面的AES加密解密

在visual studio中寫的c#代碼

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Security.Cryptography;namespace test{  class Class1  {    static void Main(string[] args)    {      Console.WriteLine("I am comming");      String source = "Test String";      String encryptData = Class1.Encrypt(source, "1234567812345678", "1234567812345678");      Console.WriteLine("=1==");      Console.WriteLine(encryptData);      Console.WriteLine("=2==");      String decryptData = Class1.Decrypt("2fbwW9+8vPId2/foafZq6Q==", "1234567812345678", "1234567812345678");      Console.WriteLine(decryptData);      Console.WriteLine("=3==");      Console.WriteLine("I will go out");    }    public static string Encrypt(string toEncrypt, string key, string iv)    {      byte[] keyArray = UTF8Encoding.UTF8.GetBytes(key);      byte[] ivArray = UTF8Encoding.UTF8.GetBytes(iv);      byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(toEncrypt);      RijndaelManaged rDel = new RijndaelManaged();      rDel.Key = keyArray;      rDel.IV = ivArray;      rDel.Mode = CipherMode.CBC;      rDel.Padding = PaddingMode.Zeros;      ICryptoTransform cTransform = rDel.CreateEncryptor();      byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);      return Convert.ToBase64String(resultArray, 0, resultArray.Length);    }    public static string Decrypt(string toDecrypt, string key, string iv)    {      byte[] keyArray = UTF8Encoding.UTF8.GetBytes(key);      byte[] ivArray = UTF8Encoding.UTF8.GetBytes(iv);      byte[] toEncryptArray = Convert.FromBase64String(toDecrypt);      RijndaelManaged rDel = new RijndaelManaged();      rDel.Key = keyArray;      rDel.IV = ivArray;      rDel.Mode = CipherMode.CBC;      rDel.Padding = PaddingMode.Zeros;      ICryptoTransform cTransform = rDel.CreateDecryptor();      byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);      return UTF8Encoding.UTF8.GetString(resultArray);    }  }}

其中加密後以及解密後的字串都能成功列印,但Console.WriteLine("=3==");之後的輸出就沒有了,最後輸出個線程傳回值0,然後就沒有然後了。c#不懂,就不深究了,就已執行的部分,是符合要求了。 Java的AES加密解密:

java代碼,測試也是可以的

import javax.crypto.Cipher;import javax.crypto.spec.IvParameterSpec;import javax.crypto.spec.SecretKeySpec;import org.junit.Test;...  @Test  public void testCrossLanguageEncrypt() throws Exception{    System.out.println(encrypt());    System.out.println(desEncrypt());  }  public static String encrypt() throws Exception {    try {      String data = "Test String";      String key = "1234567812345678";      String iv = "1234567812345678";      Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");      int blockSize = cipher.getBlockSize();      byte[] dataBytes = data.getBytes();      int plaintextLength = dataBytes.length;      if (plaintextLength % blockSize != 0) {        plaintextLength = plaintextLength + (blockSize - (plaintextLength % blockSize));      }      byte[] plaintext = new byte[plaintextLength];      System.arraycopy(dataBytes, 0, plaintext, 0, dataBytes.length);      SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(), "AES");      IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes());      cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec);      byte[] encrypted = cipher.doFinal(plaintext);      return new sun.misc.BASE64Encoder().encode(encrypted);    } catch (Exception e) {      e.printStackTrace();      return null;    }  }  public static String desEncrypt() throws Exception {    try    {      String data = "2fbwW9+8vPId2/foafZq6Q==";      String key = "1234567812345678";      String iv = "1234567812345678";      byte[] encrypted1 = new sun.misc.BASE64Decoder().decodeBuffer(data);      Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");      SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(), "AES");      IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes());      cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec);      byte[] original = cipher.doFinal(encrypted1);      String originalString = new String(original);      return originalString;    }    catch (Exception e) {      e.printStackTrace();      return null;    }  }
php的AES加密解密

php代碼,php很多東西都是提供好的,直接用函數,但是php目前所知填充模式只有ZeroPadding,於是其他語言就只能跟著它來了:

<?php$privateKey = "1234567812345678";$iv     = "1234567812345678";$data   = "Test String";//加密$encrypted = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $privateKey, $data, MCRYPT_MODE_CBC, $iv);echo($encrypted);echo '<br/>';echo(base64_encode($encrypted));echo '<br/>';//解密$encryptedData = base64_decode("2fbwW9+8vPId2/foafZq6Q==");$decrypted = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $privateKey, $encryptedData, MCRYPT_MODE_CBC, $iv);echo($decrypted);?>

Javascript下aes加解密,試過也可以,需要在https://code.google.com/p/crypto-js/下載工具包

<script type="text/javascript" src="aes.js"></script>    <script type="text/javascript" src="pad-zeropadding.js"></script>

匯入檔案,aes.js需要匯入crypto-js壓縮包中rollups檔案夾下的那個aes.js檔案,如果引入的是components檔案夾下的aes.js是會報錯的

<script type="text/javascript">  var data = "Test String";  var key  = CryptoJS.enc.Latin1.parse('1234567812345678');  var iv   = CryptoJS.enc.Latin1.parse('1234567812345678');  //加密  var encrypted = CryptoJS.AES.encrypt(data,key,{iv:iv,mode:CryptoJS.mode.CBC,padding:CryptoJS.pad.ZeroPadding});  document.write(encrypted.ciphertext);  document.write('<br/>');  document.write(encrypted.key);  document.write('<br/>');  document.write(encrypted.iv);  document.write('<br/>');  document.write(encrypted.salt);  document.write('<br/>');  document.write(encrypted);  document.write('<br/>');  //解密  var decrypted = CryptoJS.AES.decrypt(encrypted,key,{iv:iv,padding:CryptoJS.pad.ZeroPadding});  console.log(decrypted.toString(CryptoJS.enc.Utf8));    </script>

成功加解密,最後解密的字串串在瀏覽器的控制台裡才能看到。 python的AES加密解密

最後加一個python下的aes,需要安裝python Crypto:

#!/usr/bin/env python# -*- coding: utf-8 -*-from Crypto.Cipher import AESimport base64PADDING = '\0'#PADDING = ' 'pad_it = lambda s: s+(16 - len(s)%16)*PADDING  key = '1234567812345678'iv = '1234567812345678'source = 'Test String'generator = AES.new(key, AES.MODE_CBC, iv)crypt = generator.encrypt(pad_it(source))   cryptedStr = base64.b64encode(crypt)print cryptedStrgenerator = AES.new(key, AES.MODE_CBC, iv)recovery = generator.decrypt(crypt)print recovery.rstrip(PADDING)

注意python下需要用'\0'來填充,如果是空格來填充,python加密得到的字串會跟其他語言不同。另外注意generator在加密的時候使用過,解密的時候需重建再解密,否則解密失敗。最後得到的字串,在python控制台看到尾部是多個NUL這樣的東西,要這樣recovery.rstrip(PADDING)去除掉才是原始字串。

可以看到aes加密的中間結果是byte[]類型,直接new String(byte[])會看不到有意義的中間結果,這裡用的是base64,是因為各個語言都有這樣的支援。在同個語言內,也有bytesToHexString這樣的方式。

跨語言加解密的要求是:AES/CBC/ZeroPadding 128位元模式,key和iv一樣,編碼統一用utf-8。不支援ZeroPadding的就用NoPadding.

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.