C#.NET与JAVA互通之AES加密解密V2024

视频:

注意点:

1. KEY 和 IV 从字符串转byte数组时,双方要约定好编码,一般是UTF8。

2.明文从字符串转byte数组时,双方要约定好编码,一般是UTF8,也可以GB2312,但不能Encoding.Default。

3.加密后的结果,从byte数组转字符串时,双方要约定好编码,一般是Base64字符串。

4.NET 的PKCS7Padding 对应 JAVA 的:PKCS5Padding
5. AES128指的是密钥长度为16个字符串(16Byte * 8 = 128 bit),AES256指的是密钥长度为32个字符串(32Byte * 8 = 256 bit)。

6.AES KEY 的变种(MD5 HASH 后,正好是AES256,或截取前16位作为AES128)

一、C#.NET:

AesUtil:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text; namespace CommonUtils
{
/// <summary>
/// AES 工具类,2024-06-07,runliuv。
/// </summary>
public static class AesUtil
{ /// <summary>
/// AES CBC 解密
/// </summary>
/// <param name="decryptStr">要解密的串,base64字符串</param>
/// <param name="aesKey">密钥</param>
/// <param name="aesIV">IV</param>
/// <returns></returns>
public static string AesDecryptCBC(string decryptStr, string aesKey, string aesIV)
{ byte[] byteKEY = Encoding.UTF8.GetBytes(aesKey);
byte[] byteIV = Encoding.UTF8.GetBytes(aesIV); byte[] byteDecrypt = Convert.FromBase64String(decryptStr); var _aes = new RijndaelManaged();
_aes.Padding = PaddingMode.PKCS7;
_aes.Mode = CipherMode.CBC; _aes.Key = byteKEY;
_aes.IV = byteIV; var _crypto = _aes.CreateDecryptor();
byte[] decrypted = _crypto.TransformFinalBlock(
byteDecrypt, 0, byteDecrypt.Length); _crypto.Dispose(); return Encoding.UTF8.GetString(decrypted);
} /// <summary>
/// AES CBC 解密,输入输出都是byte[],方便用各种编码转换成字符串
/// </summary>
/// <param name="byteDecrypt"></param>
/// <param name="byteKEY"></param>
/// <param name="byteIV"></param>
/// <returns></returns>
public static byte[] AesDecryptCBC(byte[] byteDecrypt, byte[] byteKEY, byte[] byteIV)
{ var _aes = new RijndaelManaged();
_aes.Padding = PaddingMode.PKCS7;
_aes.Mode = CipherMode.CBC; _aes.Key = byteKEY;
_aes.IV = byteIV; var _crypto = _aes.CreateDecryptor();
byte[] decrypted = _crypto.TransformFinalBlock(
byteDecrypt, 0, byteDecrypt.Length); _crypto.Dispose(); return decrypted;
} /// <summary>
/// AES CBC 加密,输出base64字符串。
/// </summary>
/// <param name="content"></param>
/// <param name="aesKey"></param>
/// <param name="aesIV"></param>
/// <returns></returns>
public static string AesEncryptCBC(string content, string aesKey, string aesIV)
{ byte[] byteKEY = Encoding.UTF8.GetBytes(aesKey);
byte[] byteIV = Encoding.UTF8.GetBytes(aesIV); byte[] byteContnet = Encoding.UTF8.GetBytes(content); var _aes = new RijndaelManaged();
_aes.Padding = PaddingMode.PKCS7;
_aes.Mode = CipherMode.CBC; _aes.Key = byteKEY;
_aes.IV = byteIV; var _crypto = _aes.CreateEncryptor();
byte[] decrypted = _crypto.TransformFinalBlock(
byteContnet, 0, byteContnet.Length); _crypto.Dispose(); return Convert.ToBase64String(decrypted);
} /// <summary>
/// AES CBC 加密,输入输出都是byte[],方便用各种编码转换成字符串
/// </summary>
/// <param name="byteContnet"></param>
/// <param name="byteKEY"></param>
/// <param name="byteIV"></param>
/// <returns></returns>
public static byte[] AesEncryptCBC(byte[] byteContnet, byte[] byteKEY, byte[] byteIV)
{ var _aes = new RijndaelManaged();
_aes.Padding = PaddingMode.PKCS7;
_aes.Mode = CipherMode.CBC; _aes.Key = byteKEY;
_aes.IV = byteIV; var _crypto = _aes.CreateEncryptor();
byte[] decrypted = _crypto.TransformFinalBlock(
byteContnet, 0, byteContnet.Length); _crypto.Dispose(); return decrypted;
} public static string AesEncryptECB(string content, string aesKey)
{ byte[] byteKEY = Encoding.UTF8.GetBytes(aesKey); byte[] byteContnet = Encoding.UTF8.GetBytes(content); var _aes = new RijndaelManaged();
_aes.Padding = PaddingMode.PKCS7;
_aes.Mode = CipherMode.ECB; _aes.Key = byteKEY; var _crypto = _aes.CreateEncryptor();
byte[] decrypted = _crypto.TransformFinalBlock(
byteContnet, 0, byteContnet.Length); _crypto.Dispose(); return Convert.ToBase64String(decrypted);
} public static string AesDecryptECB(string decryptStr, string aesKey)
{ byte[] byteKEY = Encoding.UTF8.GetBytes(aesKey); byte[] byteDecrypt = Convert.FromBase64String(decryptStr); var _aes = new RijndaelManaged();
_aes.Padding = PaddingMode.PKCS7;
_aes.Mode = CipherMode.ECB; _aes.Key = byteKEY; var _crypto = _aes.CreateDecryptor();
byte[] decrypted = _crypto.TransformFinalBlock(
byteDecrypt, 0, byteDecrypt.Length); _crypto.Dispose(); return Encoding.UTF8.GetString(decrypted);
} }
}

HashUtil

using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text; namespace CommonUtils
{
public static class HashUtil
{ public static string GetMd5(string src)
{
MD5 md = MD5.Create();
byte[] bytes = Encoding.UTF8.GetBytes(src);
byte[] buffer2 = md.ComputeHash(bytes);
string str = "";
for (int i = 0; i < buffer2.Length; i++)
{
str = str + buffer2[i].ToString("x2");
}
return str; } public static IDictionary<string, string> ModelToDic<T1>(T1 cfgItem)
{
IDictionary<string, string> sdCfgItem = new Dictionary<string, string>(); System.Reflection.PropertyInfo[] cfgItemProperties = cfgItem.GetType().GetProperties(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public);
foreach (System.Reflection.PropertyInfo item in cfgItemProperties)
{
string name = item.Name;
object value = item.GetValue(cfgItem, null);
if (value != null && (item.PropertyType.IsValueType || item.PropertyType.Name.StartsWith("String")) && !string.IsNullOrWhiteSpace(value.ToString()))
{
sdCfgItem.Add(name, value.ToString());
}
} return sdCfgItem;
} public static IDictionary<string, string> AsciiDictionary(IDictionary<string, string> sArray)
{
IDictionary<string, string> asciiDic = new Dictionary<string, string>();
string[] arrKeys = sArray.Keys.ToArray();
Array.Sort(arrKeys, string.CompareOrdinal);
foreach (var key in arrKeys)
{
string value = sArray[key];
asciiDic.Add(key, value);
}
return asciiDic;
} public static string BuildQueryString(IDictionary<string, string> sArray)
{ //拼接 K=V&A=B&c=1 这种URL StringBuilder sc = new StringBuilder(); foreach (var item in sArray)
{
string name = item.Key;
string value = item.Value;
if (!string.IsNullOrWhiteSpace(value))
{
sc.AppendFormat("{0}={1}&", name, value);
} } string fnlStr = sc.ToString();
fnlStr = fnlStr.TrimEnd('&'); return fnlStr;
} }
}

.NET 使用:

using CommonUtils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace ConsoleApp1
{
internal class Program
{
static void Main(string[] args)
{
try
{
//.NET 的PKCS7 对应 JAVA 的:PKCS5Padding
TestAesCbc(); TestAesECB(); //JAVA加密,.NET 解密
string javaStr = "FfRdTUVCFSknpYNXoMHQOAQNEqkHY1uU19u/3wWH6Js=";
Console.WriteLine("JAVA加密后的字符串:" + javaStr);
string aesKey = "1234567890123456";//AES KEY 与 JAVA 保持一致
string decryptedStr = AesUtil.AesDecryptECB(javaStr, aesKey);
Console.WriteLine("自加,自解:" + decryptedStr); //有的AES加密,不是直接把字符串当KEY使用,而是把原密钥 MD5 HASH后,作为AES 的KEY。
TestAesKeyTrap();
}
catch (Exception ex)
{
Console.WriteLine("ex!" + ex.Message);
}
Console.WriteLine("结束!");
Console.ReadKey();
} static void TestAesCbc()
{
Console.WriteLine("-- TestAesCbc --" );
string aesKey = "1234567890123456";//16位或32位
string aesIV = "abcdefghABCDEFGH"; string aa = "这边是 .net aes 加密";
Console.WriteLine("待加密字符串:" + aa);
string encryptedStr = AesUtil.AesEncryptCBC(aa, aesKey, aesIV);
Console.WriteLine("加密字符串:" + encryptedStr);
//自加,自解
string decryptedStr = AesUtil.AesDecryptCBC(encryptedStr, aesKey, aesIV);
Console.WriteLine("自加,自解:" + decryptedStr);
} static void TestAesECB()
{
Console.WriteLine("-- TestAesECB --"); string aesKey = "1234567890123456";//16位或32位 string aa = ".net aes 加密";
Console.WriteLine("待加密字符串:" + aa);
string encryptedStr = AesUtil.AesEncryptECB(aa, aesKey);
Console.WriteLine("加密字符串:" + encryptedStr);
//自加,自解
string decryptedStr = AesUtil.AesDecryptECB(encryptedStr, aesKey);
Console.WriteLine("自加,自解:" + decryptedStr);
} /// <summary>
/// AES KEY 的变种(MD5 HASH 后,正好是AES256,或截取前16位作为AES128)
/// </summary>
static void TestAesKeyTrap()
{
Console.WriteLine("-- TestAesECB --"); string orgKey = "HelloWorld";//不够16位或32位
//string aesKey = "HelloWorld";//不够16位或32位 string aesKey = HashUtil.GetMd5(orgKey).ToLower().Substring(16);
Console.WriteLine("GetMd5后的长度:" + aesKey.Length.ToString()); string aa = ".net aes 加密";
Console.WriteLine("待加密字符串:" + aa);
string encryptedStr = AesUtil.AesEncryptECB(aa, aesKey);
Console.WriteLine("加密字符串:" + encryptedStr);
//自加,自解
string decryptedStr = AesUtil.AesDecryptECB(encryptedStr, aesKey);
Console.WriteLine("自加,自解:" + decryptedStr);
}
}
}

二、JAVA:

AesUtil:

package org.runliuv;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Base64; public class AesUtil { private static final String charset = "UTF-8"; /**
* 加密
* @param content
* @param key
* @param iv
* @return
* @throws Exception
*/
public static String AesEncryptCBC(String content, String key, String iv)
throws Exception { //明文
byte[] contentBytes = content.getBytes(charset); //AES KEY
byte[] keyBytes = key.getBytes(charset);
SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES"); //AES IV
byte[] initParam = iv.getBytes(charset);
IvParameterSpec ivParameterSpec = new IvParameterSpec(initParam); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivParameterSpec);
byte[] byEnd = cipher.doFinal(contentBytes); //加密后的byte数组转BASE64字符串
String strEnd = Base64.getEncoder().encodeToString(byEnd);
return strEnd;
} /**
* 解密
* @param content
* @param key
* @param iv
* @return
* @throws Exception
*/
public static String AesDecryptCBC(String content, String key, String iv)
throws Exception {
//反向解析BASE64字符串为byte数组
byte[] encryptedBytes = Base64.getDecoder().decode(content); //AES KEY
byte[] keyBytes = key.getBytes(charset);
SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES"); //AES IV
byte[] initParam = iv.getBytes(charset);
IvParameterSpec ivParameterSpec = new IvParameterSpec(initParam); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, keySpec, ivParameterSpec);
byte[] byEnd = cipher.doFinal(encryptedBytes); //加密后的byte数组直接转字符串
String strEnd = new String(byEnd, charset);
return strEnd;
} public static String AesEncryptECB(String content, String key)
throws Exception { //明文
byte[] contentBytes = content.getBytes(charset); //AES KEY
byte[] keyBytes = key.getBytes(charset);
SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES"); Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, keySpec);
byte[] byEnd = cipher.doFinal(contentBytes); //加密后的byte数组转BASE64字符串
String strEnd = Base64.getEncoder().encodeToString(byEnd);
return strEnd;
} public static String AesDecryptECB(String content, String key)
throws Exception {
//反向解析BASE64字符串为byte数组
byte[] encryptedBytes = Base64.getDecoder().decode(content); //AES KEY
byte[] keyBytes = key.getBytes(charset);
SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES"); Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, keySpec);
byte[] byEnd = cipher.doFinal(encryptedBytes); //加密后的byte数组直接转字符串
String strEnd = new String(byEnd, charset);
return strEnd;
} }

java使用:

package org.runliuv;

/**
* Hello world!
*
*/
public class App
{
public static void main( String[] args )
{ try
{
TestAesCbc(); TestAesECB(); //.net aes cbc 加,JAVA 解密
String netStr="Mrs6Ufo2Y4ulWiksFSWFnUNKVSO5COruAlgQ5ws7FL0=";
System.out.println("-- .net 加密后的内容:" + netStr);
String aesKey = "1234567890123456";//与.net 保持一致
String aesIV = "abcdefghABCDEFGH";//与.net 保持一致 String decryptedStr = AesUtil.AesDecryptCBC(netStr, aesKey, aesIV);
System.out.println(".net aes cbc 加,JAVA 解密:" + decryptedStr); }catch (Exception ex){ System.out.println( "ex!"+ex.getMessage() );
}
System.out.println( "结束!" );
} static void TestAesCbc(){ try {
System.out.println("-- TestAesCbc --" ); //16位 (32位,jdk8 老版本,需要放JAR包才支持32位的)
String aesKey = "1234567890123456";
String aesIV = "abcdefghABCDEFGH"; String aa = "java aes 加密,2024-06-07。";
System.out.println("待加密字符串:" + aa);
String encryptedStr = AesUtil.AesEncryptCBC(aa, aesKey, aesIV);
System.out.println("加密字符串:" + encryptedStr);
//自加,自解
String decryptedStr = AesUtil.AesDecryptCBC(encryptedStr, aesKey, aesIV);
System.out.println("自加,自解:" + decryptedStr); }catch (Exception ex){ System.out.println( "ex!"+ex.getMessage() );
} } static void TestAesECB(){ try {
System.out.println("-- TestAesECB --" ); //16位 (32位,jdk8 老版本,需要放JAR包才支持32位的)
String aesKey = "1234567890123456"; String aa = "java aes 加密,2024-06-07。";
System.out.println("待加密字符串:" + aa);
String encryptedStr = AesUtil.AesEncryptECB(aa, aesKey);
System.out.println("加密字符串:" + encryptedStr);
//自加,自解
String decryptedStr = AesUtil.AesDecryptECB(encryptedStr, aesKey);
System.out.println("自加,自解:" + decryptedStr); }catch (Exception ex){ System.out.println( "ex!"+ex.getMessage() );
} }
}

-

C#.NET与JAVA互通之AES加密解密V2024的更多相关文章

  1. JAVA中使用AES加密解密

    技术交流群: 233513714 /** * AES加密测试 * * @param str 加密参数 */ public void aesTest(String str) { log.info(&qu ...

  2. c#和js互通的AES加密解密

    一.使用场景 在使用前后端分离的框架中常常会进行传输数据相互加密解密以确保数据的安全性,如web Api返回加密数据客户端或web端进行解密,或者客户端或web端进行加密提交数据服务端解密数据等等. ...

  3. php与java通用AES加密解密算法

    AES指高级加密标准(Advanced Encryption Standard),是当前最流行的一种密码算法,在web应用开发,特别是对外提供接口时经常会用到,下面是我整理的一套php与java通用的 ...

  4. C#, Java, PHP, Python和Javascript几种语言的AES加密解密实现[转载]

    原文:http://outofmemory.cn/code-snippet/35524/AES-with-javascript-java-csharp-python-or-php c#里面的AES加密 ...

  5. java使用AES加密解密 AES-128-ECB加密

    java使用AES加密解密 AES-128-ECB加密 import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; impo ...

  6. AES加密解密——AES在JavaWeb项目中前台JS加密,后台Java解密的使用

    一:前言 在软件开发中,经常要对数据进行传输,数据在传输的过程中可能被拦截,被监听,所以在传输数据的时候使用数据的原始内容进行传输的话,安全隐患是非常大的.因此就要对需要传输的数据进行在客户端进行加密 ...

  7. Java 关于密码处理的工具类[MD5编码][AES加密/解密]

    项目中又遇到了加密问题,又去翻了半天,然后做测试,干脆就把常用的两类小结一下. 1.第一种所谓的MD5加密 其实也不算加密,只是基于Hash算法的不可逆编码而已,等于说,一旦经过MD5处理,是不可能从 ...

  8. C# 实现 JAVA AES加密解密[原创]

    以下是网上普遍能收到的JAVA AES加密解密方法. 因为里面用到了KeyGenerator 和 SecureRandom,但是.NET 里面没有这2个类.无法使用安全随机数生成KEY. 我们在接收J ...

  9. 你真的了解字典(Dictionary)吗? C# Memory Cache 踩坑记录 .net 泛型 结构化CSS设计思维 WinForm POST上传与后台接收 高效实用的.NET开源项目 .net 笔试面试总结(3) .net 笔试面试总结(2) 依赖注入 C# RSA 加密 C#与Java AES 加密解密

    你真的了解字典(Dictionary)吗?   从一道亲身经历的面试题说起 半年前,我参加我现在所在公司的面试,面试官给了一道题,说有一个Y形的链表,知道起始节点,找出交叉节点.为了便于描述,我把上面 ...

  10. Java AES加密解密工具 -- GUI 、在线传输文件

    原理 对于任意长度的明文,AES首先对其进行分组,每组的长度为128位.分组之后将分别对每个128位的明文分组进行加密. 对于每个128位长度的明文分组的加密过程如下:     (1)将128位AES ...

随机推荐

  1. 力扣436(java&python)-寻找右区间(中等)

    题目: 给你一个区间数组 intervals ,其中 intervals[i] = [starti, endi] ,且每个 starti 都 不同 . 区间 i 的 右侧区间 可以记作区间 j ,并满 ...

  2. 云原生微服务的下一站,微服务引擎 MSE 重磅升级

    ​简介:管好微服务,成为云原生时代的新难题. 管好微服务,成为云原生时代的新难题. 从建好微服务到管好微服务,差的虽是一个字,连接起两边的却需要大量的微服务落地经验.因为软件架构的核心挑战是解决业务快 ...

  3. Android项目架构设计深入浅出

    ​简介:本文结合个人在架构设计上的思考和理解,介绍如何从0到1设计一个大型Android项目架构. ​ 作者 | 璞珂 来源 | 阿里技术公众号 前言:本文结合个人在架构设计上的思考和理解,介绍如何从 ...

  4. Spark 大数据处理最佳实践

    开源大数据社区 & 阿里云 EMR 系列直播 第十一期 主题:Spark 大数据处理最佳实践 讲师:简锋,阿里云 EMR 数据开发平台 负责人 内容框架: 大数据概览 如何摆脱技术小白 Spa ...

  5. 当设计模式遇上 Hooks

    ​简介: 数据结构与设计模式能够指导我们在开发复杂系统中寻得一条清晰的道路,既然都说 Hooks 难以维护,那就尝试让「神」来拯救这混乱的局面.对于「设计模式是否有助于我们写出更优雅的 Hooks 」 ...

  6. [FAQ] pdf 无法导入 adobe AI, 分辨率 or 颜色缺失 or 字体缺失

    属于Adoge软件不支持问题, 可能是分辨率.字体等多种原因. https://www.codebye.com/adobe-reader-or-acrobat-opens-pdf-file-drawi ...

  7. [FAQ] panic: listen tcp :xxxx: bind: Only one usage of each socket address (protocol/network address/port) is normally permitted.

    在 Go 中运行服务之前的绑定端口这一步,如果端口号被占用了,那么会提示它只能使用一次. 换个端口号或者检查端口号的占用程序. Link:https://www.cnblogs.com/farwish ...

  8. 一文搞懂drag&drop浏览器拖放功能的实现

    拖放功能,即将一个元素从一个区域,通过拖拽,放置到另一个区域.常见的应用是将文件或图片从一个区域,拖放到另一个区域.中文常常把这表述成拖拽,实际上拖拽的描述并不准确,应该叫拖放,因为drag事件和dr ...

  9. Solution Set - 加训 CF!

    加训一些 CF 题,这里写一些简要题解,可能是草稿. 暂定只做 Div.1 的题和 Div.1+Div.2 的后一半题.

  10. MQTT的使用一

    MQTT:物联网消息传递标准 简介 MQTT是用于物联网(IoT)的OASIS标准消息传递协议.它被设计为一种非常轻量级的发布/订阅消息传送,非常适合以较小的代码占用量和最小的网络带宽连接远程设备.如 ...