基于私钥加密公钥解密的RSA算法C#实现
RSA算法是第一个能同时用于加密和数字签名的算法,也易于理解和操作。 RSA是被研究得最广泛的公钥算法,从提出到现在已近二十年,经历了各种攻击的考验,逐渐为人们接受,普遍认为是目前最优秀的公钥方案之一。RSA的安全性依赖于大数的因子分解,但并没有从理论上证明破译RSA的难度与大数分解难度等价。
RSA的安全性依赖于大数分解。公钥和私钥都是两个大素数( 大于 100个十进制位)的函数。据猜测,从一个密钥和密文推断出明文的难度等同于分解两个大素数的积。
密钥对的产生。选择两个大素数,p 和q 。计算:
n = p * q
然后随机选择加密密钥e(PS:最常用的e值有3,17和65537,微软就是使用的65537,采用3个中的任何一个都不存在安全问题),要求 e 和 ( p - 1 ) * ( q - 1 ) 互质。最后,利用Euclid 算法计算解密密钥d, 满足
e * d = 1 ( mod ( p - 1 ) * ( q - 1 ) )
其中n和d也要互质。数e和n是公钥,d是私钥。两个素数p和q不再需要,应该丢弃,不要让任何人知道。
加密信息 m(二进制表示)时,首先把m分成等长数据块 m1 ,m2,..., mi ,块长s,其中 2^s <= n, s 尽可能的大。对应的密文是:
ci = mi^e ( mod n ) ( a )
解密时作如下计算:
mi = ci^d ( mod n ) ( b )
.NET提供常用的加密算法类,支持RSA的类是RSACryptoServiceProvider(命名空间:System.Security.Cryptography),但只支持公钥加密,私钥解密。RSACryptoServiceProvider类包括:Modulus、Exponent、P、Q、DP、DQ、InverseQ、D等8个属性,其中Modulus和Exponent就是公钥,Modulus和D就是私钥,RSACryptoServiceProvider类提供导出公钥的方法,也提供导出私钥的方法,但导出的私钥包含上面8个属性,显然要用RSACryptoServiceProvider实现私钥加密公钥是不可行的。
从RSA的原理来看,公钥加密私钥解密和私钥加密公钥解密应该是等价的,在某些情况下,比如共享软件加密,我们需要用私钥加密注册码或注册文件,发给用户,用户用公钥解密注册码或注册文件进行合法性验证。
本人利用网上找的一个C#版的大整数类BigInteger(本人认为这是偶发现的效率最高的一个C#版大整数类)来实现私钥加密公钥加密(事实上也完全支持公租加密私钥解密),但没有使用类BigInteger的大素数生成函数,而是直接使用类RSACryptoServiceProvider来生成大素数。其中加密函数和解密函数的实现如下:
/*
功能:用指定的私钥(n,d)加密指定字符串source
*/
private string EncryptString(string source, BigInteger d, BigInteger n)
{
int len = source.Length;
int len1 = 0;
int blockLen = 0;
if ((len % 128) == 0)
len1 = len / 128;
else
len1 = len / 128 + 1;
string block = "";
string temp = "";
for (int i = 0; i < len1; i++)
{
if (len >= 128)
blockLen = 128;
else
blockLen = len;
block = source.Substring(i * 128, blockLen);
byte[] oText = System.Text.Encoding.Default.GetBytes(block);
BigInteger biText = new BigInteger(oText);
BigInteger biEnText = biText.modPow(d, n);
string temp1 = biEnText.ToHexString();
temp += temp1;
len -= blockLen;
}
return temp;
}
/*
功能:用指定的公钥(n,e)解密指定字符串source
*/
private string DecryptString(string source, BigInteger e, BigInteger n)
{
int len = source.Length;
int len1 = 0;
int blockLen = 0;
if ((len % 256) == 0)
len1 = len / 256;
else
len1 = len / 256 + 1;
string block = "";
string temp = "";
for (int i = 0; i < len1; i++)
{
if (len >= 256)
blockLen = 256;
else
blockLen = len;
block = source.Substring(i * 256, blockLen);
BigInteger biText = new BigInteger(block, 16);
BigInteger biEnText = biText.modPow(e, n);
string temp1 = System.Text.Encoding.Default.GetString(biEnText.getBytes());
temp += temp1;
len -= blockLen;
}
return temp;
}
加密过程和解密过程代码如下所示:
/*
加密过程,其中d、n是RSACryptoServiceProvider生成的D、Modulus
*/
private string EncryptProcess(string source, string d, string n)
{
byte[] N = Convert.FromBase64String(n);
byte[] D = Convert.FromBase64String(d);
BigInteger biN = new BigInteger(N);
BigInteger biD = new BigInteger(D);
return EncryptString(source, biD, biN);
}
/*
解密过程,其中e、n是RSACryptoServiceProvider生成的Exponent、Modulus
*/
private string DecryptProcess(string source, string e, string n)
{
byte[] N = Convert.FromBase64String(n);
byte[] E = Convert.FromBase64String(e);
BigInteger biN = new BigInteger(N);
BigInteger biE = new BigInteger(E);
return DecryptString(source, biE, biN);
}
基于私钥加密公钥解密的RSA算法C#实现的更多相关文章
- 银联手机支付(.Net Csharp),3DES加密解密,RSA加密解密,RSA私钥加密公钥解密,.Net RSA 3DES C#
前段时间做的银联支付,折腾了好久,拼凑的一些代码,有需要的朋友可以参考,本人.Net新手,不保证准确性! 这个银联手机支付没有SDK提供,技术支持也没有.Net的,真心不好搞! RSA加解密,这里有个 ...
- RSA不对称加密,公钥加密私钥解密,私钥加密公钥解密
RSA算法是第一个能同时用于加密和数字签名的算法,也易于理解和操作. RSA是被研究得最广泛的公钥算法,从提出到现在已近二十年,经历了各种攻击的考验,逐渐为人们接受,普遍认为是目前最优秀的公钥方案之一 ...
- RSA 加密算法 Java 公钥加密私钥解密 和 私钥加密公钥解密 的特点
package com.smt.cipher.unsymmetry; import org.apache.commons.codec.binary.Base64; import org.apache. ...
- 求求你们不要再用 RSA 私钥加密公钥解密了,这非常不安全!
最近经常在网上看到有人说巨硬的 CNG(Cryptography Next Generation 即下一代加密技术) 只提供 RSA 公钥加密私钥解密,没有提供 RSA 私钥加密公钥解密,他们要自己封 ...
- golang 私钥"加密"公钥"解密"
---恢复内容开始--- 之前工作主要使用C/C++与银行/第三方支付对接,但C/C++无法满足客户"当天给协议明天实盘上载"的开发速度以及现公司一些特殊情况,所以决定用go来 ...
- C# 基于大整数类的RSA算法实现(公钥加密私钥解密,私钥加密公钥解密)
但是C#自带的RSA算法类RSACryptoServiceProvider只支持公钥加密私钥解密,即数字证书的使用. 所以参考了一些网上的资料写了一个RSA的算法实现.算法实现是基于网上提供的一个大整 ...
- RSA公钥加密-私钥解密/私钥加密-公钥解密
package com.tebon.ams.util;import org.apache.commons.codec.binary.Base64;import org.apache.log4j.Log ...
- NetCore 生成RSA公私钥对,公钥加密私钥解密,私钥加密公钥解密
using Newtonsoft.Json; using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto.Encodings; using ...
- RSA加解密 私钥加密公钥解密 私加公解 && C++ 调用openssl库 的代码实例
前提:秘钥长度=1024 ============================================== 对一片(117字节)明文加密 私加 ===================== ...
随机推荐
- Delphi实现文件关联
文件关联为我们带来很多的方便.Delphi自带有注册表对象TRegistry,可以通过它取得或改变注册表相关键值的内容. Function GetAssociatedExec(FileExt: Str ...
- 搭建Eclipse、Resin Web开发环境
搭建Eclipse.Resin Web开发环境 一.当然是安装java开发环境 参看: Java环境的搭建 http://www.cnblogs.com/ghj1976/archive/2010/04 ...
- 【LeetCode 238】Product of Array Except Self
Given an array of n integers where n > 1, nums, return an array output such that output[i] is equ ...
- 安装配置Apache
1.更新和升级系统 sudo apt-get update sudo apt-get upgrade 2.安装和配置apache 2.1.安装apache sudo apt-get install a ...
- Vs2015 win10虚拟机启动问题:无法设置UDP端口 解决方法 合集(转载)
刚装的vs2015 社区版 出现这个问题,wp8.1和win10m模拟器都无法启动,找了好久找到的解决方案,放这儿供大家参考,免得大家像我一样走弯路: Windows Phone emulator n ...
- Ansible的条件语句
此篇主要讲述的ansible的condition,主要是用条件进行一些判断,此篇为官方文档的翻译,没有进行相关的测试,后续会写入相关的测试. Ansible的条件语句 1. 前言 在有的时候pl ...
- <System.ServiceModel>
實例: <system.serviceModel> <diagnostics performanceCounters="All" /> < ...
- 硬盘类型和Linux的分区
目前硬盘主要分为以下几种:IDE,SCSI,SATA,SAS.其中SAS(Serial Attached SCSI)即串行连接SCSI,属于SCSI的新一代技术. 以下是Linux常见设备的名称: 装 ...
- linux中的配置文件
/etc/profile:此文件为系统的每个用户设置环境信息,当用户第一次登录时,该文件被执行.并从/etc/profile.d目录的配置文件中搜集shell的设置. /etc/bashrc:为每一个 ...
- linux进程控制命令
& 加在一个命令的最后,可以把这个命令放到后台执行 ,如gftp &. ctrl + z 可以将一个正在前台执行的命令放到后台,并且处于暂停状态,不可执行. jobs 查看当前有多少在 ...