美文网首页
关于AES加密

关于AES加密

作者: wh_mouse | 来源:发表于2017-07-13 11:58 被阅读440次

    以下为本人亲测的加密算法(包含PHP、iOS、JAVA以及微信小程序之间的加解密)

    一、PHP

    <?php
    class CryptAES
    {
        protected $cipher = MCRYPT_RIJNDAEL_128;
        protected $mode = MCRYPT_MODE_ECB;
        protected $pad_method = NULL;
        protected $secret_key = '';
        protected $iv = '';
     
        public function set_cipher($cipher)
        {
            $this->cipher = $cipher;
        }
     
        public function set_mode($mode)
        {
            $this->mode = $mode;
        }
     
        public function set_iv($iv)
        {
            $this->iv = $iv;
        }
     
        public function set_key($key)
        {
            $this->secret_key = $key;
        }
     
        public function require_pkcs5()
        {
            $this->pad_method = 'pkcs5';
        }
     
        protected function pad_or_unpad($str, $ext)
        {
            if ( is_null($this->pad_method) )
            {
                return $str;
            }
            else
            {
                $func_name = __CLASS__ . '::' . $this->pad_method . '_' . $ext . 'pad';
                if ( is_callable($func_name) )
                {
                    $size = mcrypt_get_block_size($this->cipher, $this->mode);
                    return call_user_func($func_name, $str, $size);
                }
            }
            return $str;
        }
     
        protected function pad($str)
        {
            return $this->pad_or_unpad($str, '');
        }
     
        protected function unpad($str)
        {
            return $this->pad_or_unpad($str, 'un');
        }
     
        public function encrypt($str)
        {
            $str = $this->pad($str);
            $td = mcrypt_module_open($this->cipher, '', $this->mode, '');
     
            if ( empty($this->iv) )
            {
                $iv = @mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
            }
            else
            {
                $iv = $this->iv;
            }
     
            mcrypt_generic_init($td, $this->secret_key, $iv);
            $cyper_text = mcrypt_generic($td, $str);
            $rt=base64_encode($cyper_text);
            //$rt = bin2hex($cyper_text);
            mcrypt_generic_deinit($td);
            mcrypt_module_close($td);
     
            return $rt;
        }
     
        public function decrypt($str){
            $td = mcrypt_module_open($this->cipher, '', $this->mode, '');
     
            if ( empty($this->iv) )
            {
                $iv = @mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
            }
            else
            {
                $iv = $this->iv;
            }
     
            mcrypt_generic_init($td, $this->secret_key, $iv);
            //$decrypted_text = mdecrypt_generic($td, self::hex2bin($str));
            $decrypted_text = mdecrypt_generic($td, base64_decode($str));
            $rt = $decrypted_text;
            mcrypt_generic_deinit($td);
            mcrypt_module_close($td);
     
            return $this->unpad($rt);
        }
     
        public static function hex2bin($hexdata) {
            $bindata = '';
            $length = strlen($hexdata);
            for ($i=0; $i amp;< $length; $i += 2)
            {
                $bindata .= chr(hexdec(substr($hexdata, $i, 2)));
            }
            return $bindata;
        }
     
        public static function pkcs5_pad($text, $blocksize)
        {
            $pad = $blocksize - (strlen($text) % $blocksize);
            return $text . str_repeat(chr($pad), $pad);
        }
     
        public static function pkcs5_unpad($text)
        {
            $pad = ord($text{strlen($text) - 1});
            if ($pad > strlen($text)) return false;
            if (strspn($text, chr($pad), strlen($text) - $pad) != $pad) return false;
            return substr($text, 0, -1 * $pad);
        }
    }
     
    $keyStr = 'UITN25LMUQC436IM';
    $plainText = 'this is a string will be AES_Encrypt';
     
    $aes = new CryptAES();
    $aes->set_key($keyStr);
    $aes->require_pkcs5();
    $encText = $aes->encrypt($plainText);
    $decString = $aes->decrypt($encText);
     
    echo $encText,"n",$decString;
     
    ?>
    

    运行结果

    fhTD0NNIzv4jUEhJuC1htFFXJ/4S/rL6tDCJPiNvJ8mVLHWOD0HWweuxHynxoZf9
    this is a string will be AES_Encrypt
    

    二、iOS

    1> NAData+AES.h

    #import <Foundation/Foundation.h>
    #import <CommonCrypto/CommonDigest.h>
    #import <CommonCrypto/CommonCryptor.h>
    
    @interface NSData (AES)
    
    //加密
    - (NSString *)AES256_Encrypt;
    
    //解密
    +(NSString*)AES256_Decrypt:(NSString*)strForEncode;
    - (NSData *) AES256_Decrypt;
    //追加64编码
    - (NSString *)newStringInBase64FromData;
    
    //同上64编码
    + (NSString*)base64encode:(NSString*)str;
    
    
    @end
    

    2> NAData+AES.m

    #import "NSData+AES.h"
    
    #define SecretKey  @"yourSecretKey"
    static char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
    
    @implementation NSData (AES)
    //加密
    - (NSString *) AES256_Encrypt{
        char keyPtr[kCCKeySizeAES256+1];
        bzero(keyPtr, sizeof(keyPtr));
        [SecretKey getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
        NSUInteger dataLength = [self length];
        size_t bufferSize = dataLength + kCCBlockSizeAES128;
        void *buffer = malloc(bufferSize);
        size_t numBytesEncrypted = 0;
        CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128,
                                              kCCOptionPKCS7Padding | kCCOptionECBMode,
                                              keyPtr, kCCBlockSizeAES128,
                                              NULL,
                                              [self bytes], dataLength,
                                              buffer, bufferSize,
                                              &numBytesEncrypted);
        if (cryptStatus == kCCSuccess) {
            NSData *decodeData =[NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
            return [decodeData base64EncodedStringWithOptions:0];
        }
        free(buffer);
        return nil;
    }
    
    +(NSString*)AES256_Decrypt:(NSString*)strForEncode{
        NSData *dddd = [[NSData alloc]initWithBase64EncodedString:strForEncode options:0];
        NSData *pp  = [dddd AES256_Decrypt];
        if (pp == nil) {
            NSLog(@"解密错误!");
            return nil;
        }else{
            return  [[NSString alloc] initWithData:pp encoding:NSUTF8StringEncoding];
        }
    }
    
    //解密
    - (NSData *) AES256_Decrypt{
        char keyPtr[kCCKeySizeAES256+1];
        bzero(keyPtr, sizeof(keyPtr));
        [SecretKey getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
        NSUInteger dataLength = [self length];
        size_t bufferSize = dataLength + kCCBlockSizeAES128;
        void *buffer = malloc(bufferSize);
        size_t numBytesDecrypted = 0;
        CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES128,
                                              kCCOptionPKCS7Padding | kCCOptionECBMode,
                                              keyPtr, kCCBlockSizeAES128,
                                              NULL,
                                              [self bytes], dataLength,
                                              buffer, bufferSize,
                                              &numBytesDecrypted);
        if (cryptStatus == kCCSuccess) {
            return [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted];
        }
        free(buffer);
        return nil;
    }
    
    - (NSString *)newStringInBase64FromData            //追加64编码
    {
        
        NSMutableString *dest = [[NSMutableString alloc] initWithString:@""];
        unsigned char * working = (unsigned char *)[self bytes];
        int srcLen = (int)[self length];
       
        for (int i=0; i<srcLen; i += 3) {
            
            for (int nib=0; nib<4; nib++) {
                int byt = (nib == 0)?0:nib-1;
                int ix = (nib+1)*2;
                if (i+byt >= srcLen) break;
                
                unsigned char curr = ((working[i+byt] << (8-ix)) & 0x3F);
                if (i+nib < srcLen) curr |= ((working[i+nib] >> ix) & 0x3F);
                [dest appendFormat:@"%c", base64[curr]];
            }
        }
        return dest;
    }
    
    + (NSString*)base64encode:(NSString*)str
    {
        if ([str length] == 0)   return @"";
        
        const char *source = [str UTF8String];
        int strlength  = (int)strlen(source);
        char *characters = malloc(((strlength + 2) / 3) * 4);
        if (characters == NULL)   return nil;
        
        NSUInteger length = 0;
        NSUInteger i = 0;
        while (i < strlength) {
            char buffer[3] = {0,0,0};
            short bufferLength = 0;
            while (bufferLength < 3 && i < strlength)
                buffer[bufferLength++] = source[i++];
            characters[length++] = base64[(buffer[0] & 0xFC) >> 2];
            characters[length++] = base64[((buffer[0] & 0x03) << 4) | ((buffer[1] & 0xF0) >> 4)];
            if (bufferLength > 1)
                characters[length++] = base64[((buffer[1] & 0x0F) << 2) | ((buffer[2] & 0xC0) >> 6)];
            else characters[length++] = '=';
            if (bufferLength > 2)
                characters[length++] = base64[buffer[2] & 0x3F];
            else characters[length++] = '=';
        }
        NSString *g = [[NSString alloc] initWithBytesNoCopy:characters length:length encoding:NSASCIIStringEncoding freeWhenDone:YES];
        
        return g;
    }
    @end
    
    

    3> NSString+AES.h

    #import <Foundation/Foundation.h>
    #import "NSData+AES.h"
    
    @interface NSString (AES)
    
    //加密
    - (NSString *) AES256_Encrypt:(NSString *)key;
    
    //解密
    - (NSString *) AES256_Decrypt:(NSString *)key;
    
    @end
    

    4> NSString+AES.m

    #import "NSString+AES.h"
    
    @implementation NSString (AES)
    
    //加密
    - (NSString *) AES256_Encrypt{
        const char *cstr = [self cStringUsingEncoding:NSUTF8StringEncoding];
        NSData *data = [NSData dataWithBytes:cstr length:self.length];
        //对数据进行加密
        NSData *result = [data AES256_Encrypt];
        
        //转换为2进制字符串
        if (result && result.length > 0) {
            
            Byte *datas = (Byte*)[result bytes];
            NSMutableString *output = [NSMutableString stringWithCapacity:result.length * 2];
            for(int i = 0; i < result.length; i++){
                [output appendFormat:@"%02x", datas[i]];
            }
            return output;
        }
        return nil;
    }
    
    //解密
    - (NSString *) AES256_Decrypt:(NSString *)key{
        //转换为2进制Data
        NSMutableData *data = [NSMutableData dataWithCapacity:self.length / 2];
        unsigned char whole_byte;
        char byte_chars[3] = {'\0','\0','\0'};
        int i;
        for (i=0; i < [self length] / 2; i++) {
            byte_chars[0] = [self characterAtIndex:i*2];
            byte_chars[1] = [self characterAtIndex:i*2+1];
            whole_byte = strtol(byte_chars, NULL, 16);
            [data appendBytes:&whole_byte length:1];
        }
        
        //对数据进行解密
        NSData* result = [data AES256_Decrypt];
        if (result && result.length > 0) {
            return [[NSString alloc] initWithData:result encoding:NSUTF8StringEncoding];
        }
        return nil;
    }
    
    @end
    

    使用方法

    1>导入头文件
    #import "NSData+AES.h"
    
    2>使用
    NSString * accountPsw = @"123456";
    NSLog(@"加密前:%@", accountPsw);
    NSLog(@"加密后:%@",[[accountPsw dataUsingEncoding:NSUTF8StringEncoding]AES256_Encrypt]);
    NSString * encodePsw =[[accountPsw dataUsingEncoding:NSUTF8StringEncoding]AES256_Encrypt];
    NSString *decodePsw = [NSData AES256_Decrypt: encodePsw];
    NSlog(@"解密前:%@", encodePsw);
    NSlog(@"解密后:%@", decodePsw);
    

    三、Android

    1> CrypyAES.java

    package com.lzkj.myapplication.CryptAES;
    
    import android.util.Base64;
    import android.util.Log;
    
    import com.lzkj.myapplication.WH_Utility.StringUtils;
    
    import java.security.Key;
    import java.util.regex.Matcher;
    import java.util.regex.Pattern;
    
    import javax.crypto.Cipher;
    import javax.crypto.spec.SecretKeySpec;
    
    /**
     * 对称加密算法
     * Created by wenh on 2016/11/309:06.
     */
    
    public class CryptAES {
    
        private static String keyStr = "yourSecretKey";//与后台约定好的秘钥
    
        private static final String AESTYPE ="AES/ECB/PKCS5Padding";
    
        /**
         * 加密
         * @param plainText
         * @return
         */
        public static String AES_Encrypt(String plainText) {
            byte[] encrypt = null;
    //        Log.v("json"," 明文密码***** " + plainText);
            try{
                Key key = generateKey(keyStr);
                Cipher cipher = Cipher.getInstance(AESTYPE);
                cipher.init(Cipher.ENCRYPT_MODE, key);
                encrypt = cipher.doFinal(plainText.getBytes());
            }catch(Exception e){
                e.printStackTrace();
            }
            String ddd = new String(Base64.encode(encrypt,Base64.DEFAULT));
            String mkls = StringUtils.replaceBlank(ddd);//去除换行符
            return mkls;
        }
    
        /**
         * 解密
         * @param encryptData
         * @return
         */
        public static String AES_Decrypt(String encryptData) {
            byte[] decrypt = null;
            try{
                Key key = generateKey(keyStr);
                Cipher cipher = Cipher.getInstance(AESTYPE);
                cipher.init(Cipher.DECRYPT_MODE, key);
                decrypt = cipher.doFinal(Base64.decode(encryptData,Base64.DEFAULT));
            }catch(Exception e){
                e.printStackTrace();
            }
            return new String(decrypt).trim();
        }
    
        private static Key generateKey(String key)throws Exception{
            try{
                SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(), "AES");
                return keySpec;
            }catch(Exception e){
                e.printStackTrace();
                throw e;
            }
        }
    }
    

    2>使用方法

    String psw = "123456";
    Log.e("CryptAES","加密前:"+psw);
    Log.e("CryptAES","加密后:"+CryptAES.AES_Encrypt(psw));
    String encodePsw =CryptAES.AES_Encrypt(psw);
    Log.e("CryptAES","解密前:"+ encodePsw);
    Log.e("CryptAES","解密后:"+ CryptAES.AES_Decrypt(encodePsw));
    

    四、微信小程序

    1>下载crypto-js.js

    2>copy至小程序目录中,我的目录如下

    小程序目录.png

    3> login.js

    全局变量
    //注意相对路径
    var CryptoJS = require('../../lib/crypto-js/crypto-js')
    
    Page({
      data: {
        psw:'123456',
        
      },
      onLoad: function () {
        var key = CryptoJS.enc.Utf8.parse("yourSecretKey");
        var pswDecrypt = CryptoJS.AES.encrypt(this.data.psw, key, {
          mode: CryptoJS.mode.ECB,
          padding: CryptoJS.pad.Pkcs7
        });
        console.log("加密前:" + this.data.psw);
        console.log("加密后:" + pswDecrypt);
        var decryptedData = CryptoJS.AES.decrypte(pswDecrypt,key,{
          mode: CryptoJS.mode.ECB,
          padding: CryptoJS.pad.Pkcs7
        });
        var encryptedStr = decryptedData.toString(CryptoJS.enc.Utf8);
        console.log("解密后:" + encryptedStr);
      }
    })
    

    相关文章

      网友评论

          本文标题:关于AES加密

          本文链接:https://www.haomeiwen.com/subject/cxrwhxtx.html