C#, Java, PHP, Python 和 Javascript 的 AES 加密解密實現

yb22 9年前發布 | 4K 次閱讀 JavaScript 加密

c#里面的AES加密解密

其中加密后以及解密后的字符串都能成功打印,但Console.WriteLine("=3==");之后的輸出就沒有了,最后輸出個線程返回值0,然后就沒有然后了。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);
        }
    }
}

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 AES
import base64
PADDING = '\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 cryptedStr
generator = 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.

 本文由用戶 yb22 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!