.NET/android/java/iOS AES general encryption and decryption

Original address http://www.cnblogs.com/jys509/p/4768120.html

The mobile terminal is getting more and more popular. During the development process, we will always encounter scenarios that need to deal with the mobile terminal, such as dealing with .NET and android or iOS. In order to make data interaction more secure, we need to encrypt data for transmission. Today, I researched and practiced encryption in several languages, and realized the same encryption algorithm for .NET, Java (android), and iOS. I will share with you below.

There are multiple algorithm modes for AES encryption, and the available source code of the two modes are provided below.

Encryption:

  1. First encrypt the text with AES
  2. Return to Base64 transcoding

Decryption method:

  1. Base64 decode the data
  2. Perform AES decryption

1. CBC (Cipher Block Chaining, encrypted block chain) mode

It is a cyclic mode, where the ciphertext of the previous group and the plaintext of the current group are XORed and then encrypted. The purpose of this is to increase the difficulty of cracking.

  • Key
  • Key offset

The java/adroid encryption AESOperator class:

Copy code
package com.bci.wx.base.util; 

import javax.crypto.Cipher;
 import javax.crypto.spec.IvParameterSpec;
 import javax.crypto.spec.SecretKeySpec; 

import sun.misc.BASE64Decoder;
 import sun.misc.BASE64Encoder; 


/** 
 * AES is a reversible encryption algorithm. After encrypting the user’s sensitive information, the original data is encrypted by AES, and then Base64 encoding conversion is carried out; 
 */ 
public  class AESOperator { 

    /* 
     * 26 keys for encryption The letter and number composition uses AES-128-CBC encryption mode here, and the key needs to be 16 bits. 
     */ 
    private String sKey = "smkldospdosldaaa"; // key, you can modify 
    private String ivParameter = "0392039203920300"; // offset, you can modify 
    private static AESOperator instance = null;

    private AESOperator() {

    }

    public static AESOperator getInstance() {
        if (instance == null)
            instance = new AESOperator();
        return instance;
    }
    
public static String Encrypt(String encData ,String secretKey,String vector) throws Exception {
        
        if(secretKey == null) {
            return null;
        }
        if(secretKey.length() != 16) {
             return  null ; 
        } 
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding" );
         byte [] raw = secretKey.getBytes(); 
        SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES" ); 
        IvParameterSpec iv = new IvParameterSpec(vector.getBytes()); //To use CBC mode, a vector iv is needed to increase the strength of the encryption algorithm 
        cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
         byte [] encrypted = cipher.doFinal(encData. getBytes("utf-8" ));
         return  newBASE64Encoder().encode(encrypted); // Use BASE64 for transcoding here. 
    } 


    // Encrypt 
    public String encrypt(String sSrc) throws Exception { 
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding" );
         byte [] raw = sKey.getBytes(); 
        SecretKeySpec skeySpec = new SecretKeySpec(raw, " AES" ); 
        IvParameterSpec iv = new IvParameterSpec(ivParameter.getBytes()); //To use CBC mode, a vector iv is required, which can increase the strength of the encryption algorithm 
        cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
         byte[] encrypted = cipher.doFinal(sSrc.getBytes("utf-8"));
        return new BASE64Encoder().encode(encrypted);// 此处使用BASE64做转码。
    }

    // 解密
    public String decrypt(String sSrc) throws Exception {
        try {
            byte[] raw = sKey.getBytes("ASCII");
            SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            IvParameterSpec iv = new IvParameterSpec(ivParameter.getBytes());
            cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
            byte[] encrypted1 = new BASE64Decoder().decodeBuffer(sSrc);// 先用base64解密
            byte[] original = cipher.doFinal(encrypted1);
            String originalString = new String(original, "utf-8");
            return originalString;
        } catch (Exception ex) {
            return null;
        }
    }
    
    public String decrypt(String sSrc,String key,String ivs) throws Exception {
        try {
            byte[] raw = key.getBytes("ASCII");
            SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            IvParameterSpec iv = new IvParameterSpec(ivs.getBytes());
            cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
            byte[] encrypted1 = new BASE64Decoder().decodeBuffer(sSrc);// 先用base64解密
            byte[] original = cipher.doFinal(encrypted1);
            String originalString = new String(original, "utf-8");
            return originalString;
        } catch (Exception ex) {
            return null;
        }
    }
    
    public static String encodeBytes(byte[] bytes) {
        StringBuffer strBuf = new StringBuffer();

        for (int i = 0; i < bytes.length; i++) {
            strBuf.append((char) (((bytes[i] >> 4) & 0xF) + ((int) 'a')));
            strBuf.append((char) (((bytes[i]) & 0xF) + ((int) 'a')));
        }

        return strBuf.toString();
    }

    public static void main(String[] args) throws Exception {
        // 需要加密的字串
        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\"}]";
        
        // 加密
        long lStart = System.currentTimeMillis();longenString);"The encrypted string is:" + AESOperator.getInstance().encrypt(cSrc);
        System.out.println(=
        String enString

        lUseTime = System.currentTimeMillis()- lStart; 
        System.out.println( "Encryption time:" + lUseTime + "milliseconds" );
         // Decrypt 
        lStart = System.currentTimeMillis(); 
        String DeString = AESOperator.getInstance(). decrypt(enString); 
        System.out.println( "The decrypted string is:" + DeString); 
        lUseTime = System.currentTimeMillis()- lStart; 
        System.out.println( "Decryption time:" + lUseTime + " Milliseconds" ); 
    } 

}
Copy code

 

.NET AES encryption and decryption:

Copy code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace AES_Dome
{
    class Program
    {
        private static string key = "smkldospdosldaaa";//key,可自行修改
        private static string iv = "0392039203920300"; //偏移量,可自行修改
        static void Main(string[] args)
        {
            string encrytpData = Encrypt("abc", key, iv);
            Console.WriteLine(encrytpData);

            string decryptData = Decrypt("5z9WEequVr7qtd+WoxV+Kw==", key, iv);
            Console.WriteLine(decryptData);

            Console.ReadLine();
        }
        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.BlockSize = 128;
            rDel.KeySize = 256;
            rDel.FeedbackSize = 128;
            rDel.Padding = PaddingMode.PKCS7;
            rDel.Key = keyArray;
            rDel.IV = ivArray;
            rDel.Mode = CipherMode.CBC;

            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);

// 这里的模式,请保持和上面加密的一样。但源代码里,这个地方并没有修正,虽然也能正确解密。看到博客的朋友,请自行修改。
// 这是个人疏忽的地址,感谢@jojoka 的提醒。
            RijndaelManaged rDel = new RijndaelManaged();
            //rDel.Key = keyArray;
            //rDel.IV = ivArray;
            //rDel.Mode = CipherMode.CBC;
            //rDel.Padding = PaddingMode.Zeros;
        rDel.BlockSize = 128;
            rDel.KeySize = 256;
            rDel.FeedbackSize = 128;
            rDel.Padding = PaddingMode.PKCS7;
            rDel.Key = keyArray;
            rDel.IV = ivArray;
            rDel.Mode = CipherMode.CBC;
    ICryptoTransform cTransform = rDel.CreateDecryptor(); 

    byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length); 

    return UTF8Encoding.UTF8.GetString(resultArray);
   }
  }
}
Copy code

 

iOS源码,请下载源码,源码里有包含。

java,.net,iOS,android通用AES加密解密源码:点击下载

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

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

只需要提供密码即可。

iOS, android, java source code has been adjusted: source download

AES online encryption and decryption verification tool:  http://www.seacha.com/tools/aes.html


Guess you like

Origin blog.csdn.net/lv842586821/article/details/78021655