RSA 加密/解密—PKCS8 (Java与C#互通BouncyCastle)

2024-06-17 09:38

本文主要是介绍RSA 加密/解密—PKCS8 (Java与C#互通BouncyCastle),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前提:

需要调用JavaAPI进行签名/验签、加密/解密,需要使用BouncyCastle 类库进行Java与C#之间的数据互通。

 

加密理解点:

1:java 私钥采用的是PKCS8 ;C# 私钥采用的是PKCS1 格式

2:RSA加密 公钥加密,私钥解密或者私钥加密和公钥解密【这点和签名sign不同,sign需要私钥签名】

3:如果 java RSA加密 最后生成16进制 C#  也需要统一。这点一般需要确认最后生成的为base64还是16进制数据。

 

额外补充:

1:私钥,公钥注意去除空格,换行等(.Replace("\r", "").Replace("\n", "").Replace("\\s", ""))

2:加密 最后生成的一般为 byte数组 ,但是由于java中byte的范围在 [-128,127] 但是 C#中byte的范围在 [0,255]

并且使用byte不好进行对比传输,所以我们在进行签名或者加密时一般转化为字符串或者16进制。

 

BouncyCastle类库下载:

https://download.csdn.net/download/u011791378/11236710

 

******************以下时加密解密(C#与Java互通)BouncyCastle *************************

        /// <summary>/// 私钥加密2/// </summary>/// <param name="content">加密内容</param>/// <param name="PrivateKey">PKCS8私钥</param>/// <returns></returns>public string EncryptByPrivateKey2(string content, string PrivateKey){RsaKeyParameters PrivateKeyParam = (RsaKeyParameters)PrivateKeyFactory.CreateKey(Convert.FromBase64String(PrivateKey));var original = new BigInteger(Encoding.UTF8.GetBytes(content));//加密var encrypted = original.ModPow(PrivateKeyParam.Exponent, PrivateKeyParam.Modulus);//16进制return PayUtils.byteArray2HexString(encrypted.ToByteArray());//base64//return Convert.ToBase64String(encrypted.ToByteArray());}/// <summary>/// 公钥解密2/// </summary>/// <param name="content">解密内容</param>/// <param name="PublicKey">PKCS8公钥</param>/// <returns></returns>public string DecryptByPublicKey2(string content, string PublicKey){//base64//byte[] byteData = Convert.FromBase64String(content);//16进制var data = PayUtils.hexString2ByteArray(content);RsaKeyParameters PublicKeyParam = (RsaKeyParameters)PublicKeyFactory.CreateKey(Convert.FromBase64String(PublicKey));var encrypted = new BigInteger(data);//解密var decrypted = encrypted.ModPow(PublicKeyParam.Exponent, PublicKeyParam.Modulus);return Encoding.UTF8.GetString(decrypted.ToByteArray());}/// <summary>/// RSA公钥加密/// </summary>/// <param name="content">加密内容</param>/// <param name="publickey">公钥</param>/// <returns></returns>public string EncryptByPublicKey(string content, string publicKey){RsaKeyParameters publicKeyParam = (RsaKeyParameters)PublicKeyFactory.CreateKey(Convert.FromBase64String(publicKey));var original = new BigInteger(Encoding.UTF8.GetBytes(content));//加密var encrypted = original.ModPow(publicKeyParam.Exponent, publicKeyParam.Modulus);//16进制return PayUtils.byteArray2HexString(encrypted.ToByteArray());//base64//return Convert.ToBase64String(encrypted.ToByteArray());}/// <summary>/// RSA私钥解密/// </summary>/// <param name="content">解密内容</param>/// <param name="privateKey">私钥</param>/// <returns></returns>public string DecryptByPrivateKey(string content, string privateKey){//base64//byte[] byteData = Convert.FromBase64String(content);//16进制var data = PayUtils.hexString2ByteArray(content);RsaKeyParameters privateKeyParam = (RsaKeyParameters)PrivateKeyFactory.CreateKey(Convert.FromBase64String(privateKey));var encrypted = new BigInteger(data);//解密var decrypted = encrypted.ModPow(privateKeyParam.Exponent, privateKeyParam.Modulus);return Encoding.UTF8.GetString(decrypted.ToByteArray());}

*****************Bytes数组与16进制的转换*************************

        private static readonly string hexChars = "0123456789ABCDEF";/// <summary>/// Bytes数组转为16进制/// </summary>/// <param name="data"></param>/// <returns></returns>public static string byteArray2HexString(byte[] data){StringBuilder sb = new StringBuilder();for (int i = 0; i < data.Length; i++){byte lo = (byte)(0xF & data[i]);byte hi = (byte)((int)((uint)(0xF0 & data[i]) >> 4));sb.Append(hexChars.Substring(hi, 1)).Append(hexChars.Substring(lo, 1));}return sb.ToString();}/// <summary>/// 16进制转为Bytes数组/// </summary>/// <param name="hexStr"></param>/// <returns></returns>public static byte[] hexString2ByteArray(String hexStr){if (hexStr.Length % 2 != 0){return null;}byte[] data = new byte[hexStr.Length / 2];for (int i = 0; i < hexStr.Length / 2; i++){char hc = hexStr.Substring(2 * i, 1).ToCharArray()[0];//.charAt(2 * i);char lc = hexStr.Substring(2 * i + 1, 1).ToCharArray()[0];//.charAt(2 * i + 1);byte hb = hexChar2Byte(hc);byte lb = hexChar2Byte(lc);if ((hb < 0) || (lb < 0)){return null;}int n = hb << 4;data[i] = ((byte)(n + lb));}return data;}private static byte hexChar2Byte(char c){if ((c >= '0') && (c <= '9')){return (byte)(c - '0');}if ((c >= 'a') && (c <= 'f')){return (byte)(c - 'a' + 10);}if ((c >= 'A') && (c <= 'F')){return (byte)(c - 'A' + 10);}return 0;}

 

这篇关于RSA 加密/解密—PKCS8 (Java与C#互通BouncyCastle)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1069090

相关文章

详解Java如何向http/https接口发出请求

《详解Java如何向http/https接口发出请求》这篇文章主要为大家详细介绍了Java如何实现向http/https接口发出请求,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 用Java发送web请求所用到的包都在java.net下,在具体使用时可以用如下代码,你可以把它封装成一

在C#中获取端口号与系统信息的高效实践

《在C#中获取端口号与系统信息的高效实践》在现代软件开发中,尤其是系统管理、运维、监控和性能优化等场景中,了解计算机硬件和网络的状态至关重要,C#作为一种广泛应用的编程语言,提供了丰富的API来帮助开... 目录引言1. 获取端口号信息1.1 获取活动的 TCP 和 UDP 连接说明:应用场景:2. 获取硬

C#使用HttpClient进行Post请求出现超时问题的解决及优化

《C#使用HttpClient进行Post请求出现超时问题的解决及优化》最近我的控制台程序发现有时候总是出现请求超时等问题,通常好几分钟最多只有3-4个请求,在使用apipost发现并发10个5分钟也... 目录优化结论单例HttpClient连接池耗尽和并发并发异步最终优化后优化结论我直接上优化结论吧,

SpringBoot使用Apache Tika检测敏感信息

《SpringBoot使用ApacheTika检测敏感信息》ApacheTika是一个功能强大的内容分析工具,它能够从多种文件格式中提取文本、元数据以及其他结构化信息,下面我们来看看如何使用Ap... 目录Tika 主要特性1. 多格式支持2. 自动文件类型检测3. 文本和元数据提取4. 支持 OCR(光学

Java内存泄漏问题的排查、优化与最佳实践

《Java内存泄漏问题的排查、优化与最佳实践》在Java开发中,内存泄漏是一个常见且令人头疼的问题,内存泄漏指的是程序在运行过程中,已经不再使用的对象没有被及时释放,从而导致内存占用不断增加,最终... 目录引言1. 什么是内存泄漏?常见的内存泄漏情况2. 如何排查 Java 中的内存泄漏?2.1 使用 J

JAVA系统中Spring Boot应用程序的配置文件application.yml使用详解

《JAVA系统中SpringBoot应用程序的配置文件application.yml使用详解》:本文主要介绍JAVA系统中SpringBoot应用程序的配置文件application.yml的... 目录文件路径文件内容解释1. Server 配置2. Spring 配置3. Logging 配置4. Ma

Java 字符数组转字符串的常用方法

《Java字符数组转字符串的常用方法》文章总结了在Java中将字符数组转换为字符串的几种常用方法,包括使用String构造函数、String.valueOf()方法、StringBuilder以及A... 目录1. 使用String构造函数1.1 基本转换方法1.2 注意事项2. 使用String.valu

C#使用yield关键字实现提升迭代性能与效率

《C#使用yield关键字实现提升迭代性能与效率》yield关键字在C#中简化了数据迭代的方式,实现了按需生成数据,自动维护迭代状态,本文主要来聊聊如何使用yield关键字实现提升迭代性能与效率,感兴... 目录前言传统迭代和yield迭代方式对比yield延迟加载按需获取数据yield break显式示迭

java脚本使用不同版本jdk的说明介绍

《java脚本使用不同版本jdk的说明介绍》本文介绍了在Java中执行JavaScript脚本的几种方式,包括使用ScriptEngine、Nashorn和GraalVM,ScriptEngine适用... 目录Java脚本使用不同版本jdk的说明1.使用ScriptEngine执行javascript2.

c# checked和unchecked关键字的使用

《c#checked和unchecked关键字的使用》C#中的checked关键字用于启用整数运算的溢出检查,可以捕获并抛出System.OverflowException异常,而unchecked... 目录在 C# 中,checked 关键字用于启用整数运算的溢出检查。默认情况下,C# 的整数运算不会自