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编译生成多个.class文件的原理和作用

《Java编译生成多个.class文件的原理和作用》作为一名经验丰富的开发者,在Java项目中执行编译后,可能会发现一个.java源文件有时会产生多个.class文件,从技术实现层面详细剖析这一现象... 目录一、内部类机制与.class文件生成成员内部类(常规内部类)局部内部类(方法内部类)匿名内部类二、

SpringBoot实现数据库读写分离的3种方法小结

《SpringBoot实现数据库读写分离的3种方法小结》为了提高系统的读写性能和可用性,读写分离是一种经典的数据库架构模式,在SpringBoot应用中,有多种方式可以实现数据库读写分离,本文将介绍三... 目录一、数据库读写分离概述二、方案一:基于AbstractRoutingDataSource实现动态

Springboot @Autowired和@Resource的区别解析

《Springboot@Autowired和@Resource的区别解析》@Resource是JDK提供的注解,只是Spring在实现上提供了这个注解的功能支持,本文给大家介绍Springboot@... 目录【一】定义【1】@Autowired【2】@Resource【二】区别【1】包含的属性不同【2】@

springboot循环依赖问题案例代码及解决办法

《springboot循环依赖问题案例代码及解决办法》在SpringBoot中,如果两个或多个Bean之间存在循环依赖(即BeanA依赖BeanB,而BeanB又依赖BeanA),会导致Spring的... 目录1. 什么是循环依赖?2. 循环依赖的场景案例3. 解决循环依赖的常见方法方法 1:使用 @La

Java枚举类实现Key-Value映射的多种实现方式

《Java枚举类实现Key-Value映射的多种实现方式》在Java开发中,枚举(Enum)是一种特殊的类,本文将详细介绍Java枚举类实现key-value映射的多种方式,有需要的小伙伴可以根据需要... 目录前言一、基础实现方式1.1 为枚举添加属性和构造方法二、http://www.cppcns.co

Elasticsearch 在 Java 中的使用教程

《Elasticsearch在Java中的使用教程》Elasticsearch是一个分布式搜索和分析引擎,基于ApacheLucene构建,能够实现实时数据的存储、搜索、和分析,它广泛应用于全文... 目录1. Elasticsearch 简介2. 环境准备2.1 安装 Elasticsearch2.2 J

使用C#代码在PDF文档中添加、删除和替换图片

《使用C#代码在PDF文档中添加、删除和替换图片》在当今数字化文档处理场景中,动态操作PDF文档中的图像已成为企业级应用开发的核心需求之一,本文将介绍如何在.NET平台使用C#代码在PDF文档中添加、... 目录引言用C#添加图片到PDF文档用C#删除PDF文档中的图片用C#替换PDF文档中的图片引言在当

详解C#如何提取PDF文档中的图片

《详解C#如何提取PDF文档中的图片》提取图片可以将这些图像资源进行单独保存,方便后续在不同的项目中使用,下面我们就来看看如何使用C#通过代码从PDF文档中提取图片吧... 当 PDF 文件中包含有价值的图片,如艺术画作、设计素材、报告图表等,提取图片可以将这些图像资源进行单独保存,方便后续在不同的项目中使

Java中的String.valueOf()和toString()方法区别小结

《Java中的String.valueOf()和toString()方法区别小结》字符串操作是开发者日常编程任务中不可或缺的一部分,转换为字符串是一种常见需求,其中最常见的就是String.value... 目录String.valueOf()方法方法定义方法实现使用示例使用场景toString()方法方法

Java中List的contains()方法的使用小结

《Java中List的contains()方法的使用小结》List的contains()方法用于检查列表中是否包含指定的元素,借助equals()方法进行判断,下面就来介绍Java中List的c... 目录详细展开1. 方法签名2. 工作原理3. 使用示例4. 注意事项总结结论:List 的 contain