zoukankan      html  css  js  c++  java
  • .NET/android/java/iOS AES通用加密解密

    转自【七七

    移动端越来越火了,我们在开发过程中,总会碰到要和移动端打交道的场景,比如.NET和android或者iOS的打交道。为了让数据交互更安全,我们需要对数据进行加密传输。今天研究了一下,把几种语言的加密都实践了一遍,实现了.NET,java(android),iOS都同一套的加密算法,下面就分享给大家。

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

    加密方式:

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

    解密方式:

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

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

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

    • 密钥
    • 密钥偏移量

    java/adroid加密AESOperator类:

    package com.jackey.jackey_boot;
    
    import javax.crypto.Cipher;
    import javax.crypto.spec.IvParameterSpec;
    import javax.crypto.spec.SecretKeySpec;
    
    import sun.misc.BASE64Decoder;
    import sun.misc.BASE64Encoder;
    
    
    /**
     * AES 是一种可逆加密算法,对用户的敏感信息加密处理 对原始数据进行AES加密后,在进行Base64编码转化;
     */
    public class AESOperator {
    
        /*
         * 加密用的Key 可以用26个字母和数字组成 此处使用AES-128-CBC加密模式,key需要为16位。
         */
        private String sKey = "smkldospdosldaaa";//key,可自行修改
        private String ivParameter = "3!9203abc3203@_@";//偏移量,可自行修改
        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());// 使用CBC模式,需要一个向量iv,可增加加密算法的强度
            cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
            byte[] encrypted = cipher.doFinal(encData.getBytes("utf-8"));
            return new BASE64Encoder().encode(encrypted);// 此处使用BASE64做转码。
        }
    
    
        // 加密
        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());// 使用CBC模式,需要一个向量iv,可增加加密算法的强度
            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"}]";
            String cSrc = "wubonan@_@\!\~";
            // 加密
            long lStart = System.currentTimeMillis();
            String enString = AESOperator.getInstance().encrypt(cSrc);
            System.out.println("加密后的字串是:" + enString);
    
            long lUseTime = System.currentTimeMillis() - lStart;
            System.out.println("加密耗时:" + lUseTime + "毫秒");
            // 解密
            lStart = System.currentTimeMillis();
            String DeString = AESOperator.getInstance().decrypt(enString);
            System.out.println("解密后的字串是:" + DeString);
            lUseTime = System.currentTimeMillis() - lStart;
            System.out.println("解密耗时:" + lUseTime + "毫秒");
        }
    
    }

    .NET AES加密解密:

    class Program
        {
            private static string key = "smkldospdosldaaa";//key,可自行修改
            private static string iv = "3!2019@_@"; //偏移量,可自行修改
            static void Main(string[] args)
            {
                string encrytpData = Encrypt("wubonan@_@\!\~");
                Console.WriteLine(encrytpData);
    
                string decryptData = Decrypt("p9CEDP9W/fqCtynjzRLNxw==");
                Console.WriteLine(decryptData);
    
                Console.ReadLine();
            }
            public static string Encrypt(string toEncrypt)
            {
                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)
            {
                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);
            }
        }
    作者:chenze
    出处:https://www.cnblogs.com/chenze-Index/
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
    如果文中有什么错误,欢迎指出。以免更多的人被误导。
  • 相关阅读:
    leetcode 33. Search in Rotated Sorted Array
    leetcode 32. Longest Valid Parentheses
    leetcode 28. Implement strStr()
    leetcode 27. Remove Element
    leetcode 26. Remove Duplicates from Sorted Array
    leetcode 24. Swap Nodes in Pairs
    leetcode 22. Generate Parentheses
    树莓派的频率管理和热控制
    sql执行insert插入一条记录同时获取刚插入的id
    全程直播个人博客重构过程,采用springboot+dubbo+jpa技术栈。
  • 原文地址:https://www.cnblogs.com/chenze-Index/p/11752024.html
Copyright © 2011-2022 走看看