zoukankan      html  css  js  c++  java
  • .NET/android/java/iOS AES通用加密解密(修正安卓)

    移动端越来越火了,我们在开发过程中,总会碰到要和移动端打交道的场景,比如.NET和android或者iOS的打交道。为了让数据交互更安全,我们需要对数据进行加密传输。今天研究了一下,把几种语言的加密都实践了一遍,实现了.NET,java(android),iOS都同一套的加密算法,下面就分享给大家。(转载自:http://www.cnblogs.com/jys509/p/4768120.html 有对安卓的代码单独贴出。)

    AES加密有多种算法模式,下面提供两套模式的可用源码。

    加密方式:

    1. 先将文本AES加密
    2. 返回Base64转码

    解密方式:

    1. 将数据进行Base64解码
    2. 进行AES解密

    一、CBC(Cipher Block Chaining,加密块链)模式

    是一种循环模式,前一个分组的密文和当前分组的明文异或操作后再加密,这样做的目的是增强破解难度.

    • 密钥
    • 密钥偏移量

    java加密AESOperator类:

      1 package com.bci.wx.base.util;
      2 
      3 import javax.crypto.Cipher;
      4 import javax.crypto.spec.IvParameterSpec;
      5 import javax.crypto.spec.SecretKeySpec;
      6 
      7 import sun.misc.BASE64Decoder;
      8 import sun.misc.BASE64Encoder;
      9 
     10 
     11 /**
     12  * AES 是一种可逆加密算法,对用户的敏感信息加密处理 对原始数据进行AES加密后,在进行Base64编码转化;
     13  */
     14 public class AESOperator {
     15 
     16     /*
     17      * 加密用的Key 可以用26个字母和数字组成 此处使用AES-128-CBC加密模式,key需要为16位。
     18      */
     19     private String sKey = "smkldospdosldaaa";//key,可自行修改
     20     private String ivParameter = "0392039203920300";//偏移量,可自行修改
     21     private static AESOperator instance = null;
     22 
     23     private AESOperator() {
     24 
     25     }
     26 
     27     public static AESOperator getInstance() {
     28         if (instance == null)
     29             instance = new AESOperator();
     30         return instance;
     31     }
     32     
     33 public static String Encrypt(String encData ,String secretKey,String vector) throws Exception {
     34         
     35         if(secretKey == null) {
     36             return null;
     37         }
     38         if(secretKey.length() != 16) {
     39             return null;
     40         }
     41         Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
     42         byte[] raw = secretKey.getBytes();
     43         SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
     44         IvParameterSpec iv = new IvParameterSpec(vector.getBytes());// 使用CBC模式,需要一个向量iv,可增加加密算法的强度
     45         cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
     46         byte[] encrypted = cipher.doFinal(encData.getBytes("utf-8"));
     47         return new BASE64Encoder().encode(encrypted);// 此处使用BASE64做转码。
     48     }
     49 
     50 
     51     // 加密
     52     public String encrypt(String sSrc) throws Exception {
     53         Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
     54         byte[] raw = sKey.getBytes();
     55         SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
     56         IvParameterSpec iv = new IvParameterSpec(ivParameter.getBytes());// 使用CBC模式,需要一个向量iv,可增加加密算法的强度
     57         cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
     58         byte[] encrypted = cipher.doFinal(sSrc.getBytes("utf-8"));
     59         return new BASE64Encoder().encode(encrypted);// 此处使用BASE64做转码。
     60     }
     61 
     62     // 解密
     63     public String decrypt(String sSrc) throws Exception {
     64         try {
     65             byte[] raw = sKey.getBytes("ASCII");
     66             SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
     67             Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
     68             IvParameterSpec iv = new IvParameterSpec(ivParameter.getBytes());
     69             cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
     70             byte[] encrypted1 = new BASE64Decoder().decodeBuffer(sSrc);// 先用base64解密
     71             byte[] original = cipher.doFinal(encrypted1);
     72             String originalString = new String(original, "utf-8");
     73             return originalString;
     74         } catch (Exception ex) {
     75             return null;
     76         }
     77     }
     78     
     79     public String decrypt(String sSrc,String key,String ivs) throws Exception {
     80         try {
     81             byte[] raw = key.getBytes("ASCII");
     82             SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
     83             Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
     84             IvParameterSpec iv = new IvParameterSpec(ivs.getBytes());
     85             cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
     86             byte[] encrypted1 = new BASE64Decoder().decodeBuffer(sSrc);// 先用base64解密
     87             byte[] original = cipher.doFinal(encrypted1);
     88             String originalString = new String(original, "utf-8");
     89             return originalString;
     90         } catch (Exception ex) {
     91             return null;
     92         }
     93     }
     94     
     95     public static String encodeBytes(byte[] bytes) {
     96         StringBuffer strBuf = new StringBuffer();
     97 
     98         for (int i = 0; i < bytes.length; i++) {
     99             strBuf.append((char) (((bytes[i] >> 4) & 0xF) + ((int) 'a')));
    100             strBuf.append((char) (((bytes[i]) & 0xF) + ((int) 'a')));
    101         }
    102 
    103         return strBuf.toString();
    104     }
    105 
    106     public static void main(String[] args) throws Exception {
    107         // 需要加密的字串
    108         String cSrc = "[{"request_no":"1001","service_code":"FS0001","contract_id":"100002","order_id":"0","phone_id":"13913996922","plat_offer_id":"100094","channel_id":"1","activity_id":"100045"}]";
    109         
    110         // 加密
    111         long lStart = System.currentTimeMillis();
    112         String enString = AESOperator.getInstance().encrypt(cSrc);
    113         System.out.println("加密后的字串是:" + enString);
    114 
    115         long lUseTime = System.currentTimeMillis() - lStart;
    116         System.out.println("加密耗时:" + lUseTime + "毫秒");
    117         // 解密
    118         lStart = System.currentTimeMillis();
    119         String DeString = AESOperator.getInstance().decrypt(enString);
    120         System.out.println("解密后的字串是:" + DeString);
    121         lUseTime = System.currentTimeMillis() - lStart;
    122         System.out.println("解密耗时:" + lUseTime + "毫秒");
    123     }
    124 
    125 }

    Android加密AESOperator类:(以下红色部分是JAVA和安卓代码不同的地方,安卓代码里面和IOS,c#结果一样的加密/解密方法是Encrypt64/Decrypt64)

      1 package com.example.demo2;
      2 
      3 import javax.crypto.Cipher;
      4 import javax.crypto.spec.IvParameterSpec;
      5 import javax.crypto.spec.SecretKeySpec;
      6 
      7 import android.util.Base64;
      8 
      9 public class AESEncrypto {
     10     public static byte[] _key = { 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97,
     11             98, 99, 100, 101, 102 };// 初始化矩阵
     12   public static String ivParameter="0392039203920300";
     13     // 加密
     14     public static String Encrypt64(String sSrc, String sKey) throws Exception {
     15         if (sKey == null) {
     16             System.out.print("Key为空null");
     17             return null;
     18         }
     19         // 判断Key是否为16位
     20         if (sKey.length() != 16) {
     21             System.out.print("Key长度不是16位");
     22             return null;
     23         }
     24         byte[] raw = sKey.getBytes();
     25         SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
     26         Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");// "算法/模式/补码方式"
     27         IvParameterSpec iv = new IvParameterSpec(ivParameter.getBytes());// 使用CBC模式,需要一个向量iv,可增加加密算法的强度
     28         cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
     29         byte[] encrypted = cipher.doFinal(sSrc.getBytes());
     30 
     31         return Base64.encodeToString(encrypted, 0);// 此处使用BASE64做转码功能,同时能起到2次加密的作用。
     32     }
     33 
     34     // 解密
     35     public static String Decrypt64(String sSrc, String sKey) throws Exception {
     36         try {
     37             // 判断Key是否正确
     38             if (sKey == null) {
     39                 System.out.print("Key为空null");
     40                 return null;
     41             }
     42             // 判断Key是否为16位
     43             if (sKey.length() != 16) {
     44                 System.out.print("Key长度不是16位");
     45                 return null;
     46             }
     47             byte[] raw = sKey.getBytes("ASCII");
     48             SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
     49             Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
     50             IvParameterSpec iv = new IvParameterSpec(
     51                     ivParameter.getBytes());
     52             cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
     53             byte[] encrypted1 = Base64.decode(sSrc, 0);// 先用base64解密
     54             try {
     55                 byte[] original = cipher.doFinal(encrypted1);
     56                 String originalString = new String(original);
     57                 return originalString;
     58             } catch (Exception e) {
     59                 System.out.println(e.toString());
     60                 return null;
     61             }
     62         } catch (Exception ex) {
     63             System.out.println(ex.toString());
     64             return null;
     65         }
     66     }
     67 
     68     public static String Encrypt(String sSrc, String sKey) throws Exception {
     69         if (sKey == null) {
     70             System.out.print("Key为空null");
     71             return null;
     72         }
     73         // 判断Key是否为16位
     74         if (sKey.length() != 16) {
     75             System.out.print("Key长度不是16位");
     76             return null;
     77         }
     78         byte[] raw = sKey.getBytes();
     79         SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
     80         Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
     81         IvParameterSpec iv = new IvParameterSpec(_key);
     82         cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
     83         byte[] encrypted = cipher.doFinal(sSrc.getBytes());
     84 
     85         return byte2hex(encrypted).toLowerCase();
     86     }
     87 
     88     public static String Decrypt(String sSrc, String sKey) throws Exception {
     89         try {
     90             // 判断Key是否正确
     91             if (sKey == null) {
     92                 System.out.print("Key为空null");
     93                 return null;
     94             }
     95             // 判断Key是否为16位
     96             if (sKey.length() != 16) {
     97                 System.out.print("Key长度不是16位");
     98                 return null;
     99             }
    100             byte[] raw = sKey.getBytes("ASCII");
    101             SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
    102             Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    103             IvParameterSpec iv = new IvParameterSpec(_key);
    104             cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
    105             byte[] encrypted1 = hex2byte(sSrc);
    106             try {
    107                 byte[] original = cipher.doFinal(encrypted1);
    108                 String originalString = new String(original);
    109                 return originalString;
    110             } catch (Exception e) {
    111                 System.out.println(e.toString());
    112                 return null;
    113             }
    114         } catch (Exception ex) {
    115             System.out.println(ex.toString());
    116             return null;
    117         }
    118     }
    119 
    120     public static byte[] hex2byte(String strhex) {
    121         if (strhex == null) {
    122             return null;
    123         }
    124         int l = strhex.length();
    125         if (l % 2 == 1) {
    126             return null;
    127         }
    128         byte[] b = new byte[l / 2];
    129         for (int i = 0; i != l / 2; i++) {
    130             b[i] = (byte) Integer.parseInt(strhex.substring(i * 2, i * 2 + 2),
    131                     16);
    132         }
    133         return b;
    134     }
    135 
    136     public static String byte2hex(byte[] b) {
    137         String hs = "";
    138         String stmp = "";
    139         for (int n = 0; n < b.length; n++) {
    140             stmp = (java.lang.Integer.toHexString(b[n] & 0XFF));
    141             if (stmp.length() == 1) {
    142                 hs = hs + "0" + stmp;
    143             } else {
    144                 hs = hs + stmp;
    145             }
    146         }
    147         return hs.toUpperCase();
    148     }
    149 
    150 }

    .NET AES加密解密:

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Security.Cryptography;
     5 using System.Text;
     6 using System.Threading.Tasks;
     7 
     8 namespace AES_Dome
     9 {
    10     class Program
    11     {
    12         private static string key = "smkldospdosldaaa";//key,可自行修改
    13         private static string iv = "0392039203920300"; //偏移量,可自行修改
    14         static void Main(string[] args)
    15         {
    16             string encrytpData = Encrypt("abc", key, iv);
    17             Console.WriteLine(encrytpData);
    18 
    19             string decryptData = Decrypt("5z9WEequVr7qtd+WoxV+Kw==", key, iv);
    20             Console.WriteLine(decryptData);
    21 
    22             Console.ReadLine();
    23         }
    24         public static string Encrypt(string toEncrypt, string key, string iv)
    25         {
    26             byte[] keyArray = UTF8Encoding.UTF8.GetBytes(key);
    27             byte[] ivArray = UTF8Encoding.UTF8.GetBytes(iv);
    28             byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(toEncrypt);
    29 
    30             RijndaelManaged rDel = new RijndaelManaged();
    31             rDel.BlockSize = 128;
    32             rDel.KeySize = 256;
    33             rDel.FeedbackSize = 128;
    34             rDel.Padding = PaddingMode.PKCS7;
    35             rDel.Key = keyArray;
    36             rDel.IV = ivArray;
    37             rDel.Mode = CipherMode.CBC;
    38 
    39             ICryptoTransform cTransform = rDel.CreateEncryptor();
    40             byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
    41 
    42             return Convert.ToBase64String(resultArray, 0, resultArray.Length);
    43         }
    44 
    45         public static string Decrypt(string toDecrypt, string key, string iv)
    46         {
    47             byte[] keyArray = UTF8Encoding.UTF8.GetBytes(key);
    48             byte[] ivArray = UTF8Encoding.UTF8.GetBytes(iv);
    49             byte[] toEncryptArray = Convert.FromBase64String(toDecrypt);
    50 
    51 // 这里的模式,请保持和上面加密的一样。但源代码里,这个地方并没有修正,虽然也能正确解密。看到博客的朋友,请自行修改。
    52 // 这是个人疏忽的地址,感谢@jojoka 的提醒。
    53             RijndaelManaged rDel = new RijndaelManaged();
    54             //rDel.Key = keyArray;
    55             //rDel.IV = ivArray;
    56             //rDel.Mode = CipherMode.CBC;
    57             //rDel.Padding = PaddingMode.Zeros;
    58 
    59         rDel.BlockSize = 128;
    60             rDel.KeySize = 256;
    61             rDel.FeedbackSize = 128;
    62             rDel.Padding = PaddingMode.PKCS7;
    63             rDel.Key = keyArray;
    64             rDel.IV = ivArray;
    65             rDel.Mode = CipherMode.CBC;
    66     ICryptoTransform cTransform = rDel.CreateDecryptor(); 
    67 
    68     byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length); 
    69 
    70     return UTF8Encoding.UTF8.GetString(resultArray);
    71    }
    72   }
    73 }

    二、ECB(Electronic Code Book,电子密码本)模式

    是一种基础的加密方式,密文被分割成分组长度相等的块(不足补齐),然后单独一个个加密,一个个输出组成密文。

    只需要提供密码即可。

    iOS,android,java已调通源码:源码下载

    AES在线加解密验证工具: http://www.seacha.com/tools/aes.html

  • 相关阅读:
    JavaScript笔记三两个
    形式参数分别是基本类型和引用类型的调用
    if (strAreaCode.Find("体检")>=0)
    C++编写DLL文件
    error LNK2001: unresolved external symbol __imp__closesocket@4
    accept函数
    socket编程
    MFC控件使用大全
    DLL导出函数
    LINK : fatal error LNK1104: cannot open file的解决方法
  • 原文地址:https://www.cnblogs.com/puloon/p/5542653.html
Copyright © 2011-2022 走看看