zoukankan      html  css  js  c++  java
  • C#, Java, PHP, Python和Javascript几种语言的AES加密解密实现[转载]

    原文:http://outofmemory.cn/code-snippet/35524/AES-with-javascript-java-csharp-python-or-php

    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 AES
    import base64
    PADDING = ''
    #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下需要用''来填充,如果是空格来填充,python加密得到的字符串会跟其他语言不同。另外注意generator在加密的 时候使用过,解密的时候需重新生成再解密,否则解密失败。最后得到的字符串,在python控制台看到尾部是多个NUL这样的东西,要这样 recovery.rstrip(PADDING)去除掉才是原始字符串。

    可以看到aes加密的中间结果是byte[]类型,直接new String(byte[])会看不到有意义的中间结果,这里用的是base64,是因为各个语言都有这样的支持。在同个语言内,也有bytesToHexString这样的方式。

    跨语言加解密的要求是:AES/CBC/ZeroPadding 128位模式,key和iv一样,编码统一用utf-8。不支持ZeroPadding的就用NoPadding.

  • 相关阅读:
    Digital Video Stabilization and Rolling Shutter Correction using Gyroscope 论文笔记
    Distortion-Free Wide-Angle Portraits on Camera Phones 论文笔记
    Panorama Stitching on Mobile
    Natural Image Stitching with the Global Similarity Prior 论文笔记 (三)
    Natural Image Stitching with the Global Similarity Prior 论文笔记(二)
    Natural Image Stitching with the Global Similarity Prior 论文笔记(一)
    ADCensus Stereo Matching 笔记
    Efficient Large-Scale Stereo Matching论文解析
    Setting up caffe on Ubuntu
    Kubernetes配置Secret访问Harbor私有镜像仓库
  • 原文地址:https://www.cnblogs.com/azhw/p/4566148.html
Copyright © 2011-2022 走看看