Java与Winform进行AES加解密数据传输的工具类与对应关系和示例
  9BvoR1irARnU 2023年11月13日 18 0


场景

Android+Java中使用Aes对称加密的工具类与使用:

Android+Java中使用Aes对称加密的工具类与使用_霸道流氓气质的博客-

上面讲的Java与安卓进行数据传输时使用AES加解密的示例工具类。

如果Java需要与其他第三方平台比如Winform程序进行数据传递时也需要

数据加解密。

AES

AES(高级加密标准:Advanced Encryption Standard)加密是一种对称的加密方式,用来替代原先的DES。

AES支持三种长度的密钥: 128位,192位,256位

平时大家所说的AES128,AES192,AES256,实际上就是指AES算法对不同长度密钥的使用。

三种密钥的区别:

从安全性来看,AES256安全性最高。从性能看,AES128性能最高。本质原因是它们的加密处理轮数不同。

本文采用AES的ECB模式进行加密,填充方式为PKCS5Padding,加密的密码必须为16位。编码方式统一使用UTF-8。

关于加密模式与填充模式不再详解,可自行学习,只需保证Java与Winform中对应即可。

Java AES加密中的ECB加密模式对应于C#中的System.Security.Cryptography.CipherMode.ECB模式;

Java中的PKCS5Padding填充方式,对应于C#中的System.Security.Cryptography.PaddingMode.PKCS7;

注:


实现

1、Java中进行加解密的流程与上面博客中一致

引入依赖

<!-- Aes加密-->
        <dependency>
            <groupId>org.bouncycastle</groupId>
            <artifactId>bcprov-jdk16</artifactId>
            <version>1.46</version>
        </dependency>

新建工具类

import org.apache.tomcat.util.codec.binary.Base64;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import java.util.Random;

/**
 * AES加、解密算法工具类
 */
public class AesUtils {
    /**
     * 加密算法AES
     */
    private static final String KEY_ALGORITHM = "AES";

    /**
     * key的长度,Wrong key size: must be equal to 128, 192 or 256
     * 传入时需要16、24、36
     */
    private static final Integer KEY_LENGTH = 16 * 8;

    /**
     * 算法名称/加密模式/数据填充方式
     * 默认:AES/ECB/PKCS5Padding
     */
    private static final String ALGORITHMS = "AES/ECB/PKCS5Padding";

    /**
     * 后端AES的key,由静态代码块赋值
     */
    public static String key = "badaodechengxvyu";

    static {
        key = getKey();
    }

    /**
     * 获取key
     */
    public static String getKey() {
        StringBuilder uid = new StringBuilder();
        //产生16位的强随机数
        Random rd = new SecureRandom();
        for (int i = 0; i < KEY_LENGTH / 8; i++) {
            //产生0-2的3位随机数
            int type = rd.nextInt(3);
            switch (type) {
                case 0:
                    //0-9的随机数
                    uid.append(rd.nextInt(10));
                    break;
                case 1:
                    //ASCII在65-90之间为大写,获取大写随机
                    uid.append((char) (rd.nextInt(25) + 65));
                    break;
                case 2:
                    //ASCII在97-122之间为小写,获取小写随机
                    uid.append((char) (rd.nextInt(25) + 97));
                    break;
                default:
                    break;
            }
        }
        return uid.toString();
    }

    /**
     * 加密
     *
     * @param content    加密的字符串
     * @param encryptKey key值
     */
    public static String encrypt(String content, String encryptKey) throws Exception {
        //设置Cipher对象
        Cipher cipher = Cipher.getInstance(ALGORITHMS,new BouncyCastleProvider());
        cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(encryptKey.getBytes(), KEY_ALGORITHM));

        //调用doFinal
        byte[] b = cipher.doFinal(content.getBytes(StandardCharsets.UTF_8));

        // 转base64
        return Base64.encodeBase64String(b);

    }

    /**
     * 解密
     *
     * @param encryptStr 解密的字符串
     * @param decryptKey 解密的key值
     */
    public static String decrypt(String encryptStr, String decryptKey) throws Exception {
        //base64格式的key字符串转byte
        byte[] decodeBase64 = Base64.decodeBase64(encryptStr);

        //设置Cipher对象
        Cipher cipher = Cipher.getInstance(ALGORITHMS,new BouncyCastleProvider());
        cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(decryptKey.getBytes(), KEY_ALGORITHM));

        //调用doFinal解密
        byte[] decryptBytes = cipher.doFinal(decodeBase64);
        return new String(decryptBytes);
    }
}

加解密测试

public static void main(String[] args) {

/*        String sjkey = getKey();
        System.out.println("获得随机key:" + sjkey);*/

        //16位
        String key = "badaodechengxvyu";
        //字符串
        String str = "霸道流氓气质的博客_CSDN博客-C#,架构之路,SpringBoot领域博主";
        try {
            //加密
            String encrypt = encrypt(str, key);
            //解密
            String decrypt = decrypt(encrypt, key);

            System.out.println("加密前:" + str);
            System.out.println("加密后:" + encrypt);
            System.out.println("解密后:" + decrypt);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

测试结果

Java与Winform进行AES加解密数据传输的工具类与对应关系和示例_Java

 

2、Winform中也新建工具类

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

namespace WinformStudyDemo.com.badao.utils
{
    class AESUtils
    {
    private static string key = "badaodechengxvyu";

    // AES 加密
    public static string encrypt(string str)
    {
        if (string.IsNullOrEmpty(str)) return null;
        Byte[] toEncryptArray = Encoding.UTF8.GetBytes(str);
        RijndaelManaged rm = new RijndaelManaged
        {
            Key = Encoding.UTF8.GetBytes(key),
            Mode = CipherMode.ECB,
            Padding = PaddingMode.PKCS7
        };
        ICryptoTransform cTransform = rm.CreateEncryptor();
        Byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
        return Convert.ToBase64String(resultArray, 0, resultArray.Length);
    }


    // AES 解密
    public static string decrypt(string str)
    {
        if (string.IsNullOrEmpty(str)) return null;
        Byte[] toEncryptArray = Convert.FromBase64String(str);
        RijndaelManaged rm = new RijndaelManaged
        {
            Key = Encoding.UTF8.GetBytes(key),
            Mode = CipherMode.ECB,
            Padding = PaddingMode.PKCS7
        };
        ICryptoTransform cTransform = rm.CreateDecryptor();
        Byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
        return Encoding.UTF8.GetString(resultArray);


    }
   }
}

注意与上面Java一致的key

然后进行加解密测试

//字符串
            String str = 
            try
            {
                //加密
                String encrypt = com.badao.utils.AESUtils.encrypt(str);
                //解密
                String decrypt = com.badao.utils.AESUtils.decrypt(encrypt);

                Console.WriteLine("加密前:" + str);
                Console.WriteLine("加密后:" + encrypt);
                Console.WriteLine("解密后:" + decrypt);
            }
            catch (Exception exeception)
            {
                Console.WriteLine(exeception.Message);
            }

测试结果

Java与Winform进行AES加解密数据传输的工具类与对应关系和示例_Java_02

 

3、经过对比结果一致

均为


加密后:hI/PIG/+rNC9OOqeqSILf4txnymyEAWa5FUVtBMYvNDlkpxgShSB44FKbh1HkvVg
【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月13日 0

暂无评论

推荐阅读
  nQkVcpdWfLDr   2023年11月13日   16   0   0 DesktopSystem重启
  sX9JkgY3DY86   2023年11月13日   16   0   0 圆角ci偏移量
  sX9JkgY3DY86   2023年11月13日   24   0   0 ci控件Text
9BvoR1irARnU