[ZZ]基于私钥加密公钥解密的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); 
                } 
复制代码

 

 


本文转自hyddd博客园博客,原文链接:http://www.cnblogs.com/hyddd/archive/2009/05/18/1459060.html,如需转载请自行联系原作者。


目录
相关文章
|
4月前
|
存储 搜索推荐 算法
加密算法、排序算法、字符串处理及搜索算法详解
本文涵盖四大类核心技术知识。加密算法部分介绍了对称加密(如 AES)、非对称加密(如 RSA)、哈希摘要(如 SHA-2)、签名算法的特点及密码存储方案(加盐、BCrypt 等)。 排序算法部分分类讲解了比较排序(冒泡、选择、插入、归并、快排、堆排序)和非比较排序(计数、桶、基数排序)的时间复杂度、适用场景及实现思路,强调混合排序的工业应用。 字符串处理部分包括字符串反转的双指针法,及项目中用正则进行表单校验、网页爬取、日志处理的实例。 搜索算法部分详解了二分查找的实现(双指针与中间索引计算)和回溯算法的概念(递归 + 剪枝),以 N 皇后问题为例说明回溯应用。内容全面覆盖算法原理与实践
177 0
|
5月前
|
算法 数据安全/隐私保护
基于混沌加密的遥感图像加密算法matlab仿真
本项目实现了一种基于混沌加密的遥感图像加密算法MATLAB仿真(测试版本:MATLAB2022A)。通过Logistic映射与Baker映射生成混沌序列,对遥感图像进行加密和解密处理。程序分析了加解密后图像的直方图、像素相关性、信息熵及解密图像质量等指标。结果显示,加密图像具有良好的随机性和安全性,能有效保护遥感图像中的敏感信息。该算法适用于军事、环境监测等领域,具备加密速度快、密钥空间大、安全性高的特点。
|
9月前
|
弹性计算 算法 Linux
使用SM4算法加密LUKS格式磁盘
本文介绍了在Anolis 8操作系统使用cryptsetup对磁盘进行分区、加密和挂载的过程。采用SM4加密算法。具体步骤包括:初始化加密卷、解锁加密分区、格式化并挂载设备。最后,展示了如何取消挂载并关闭加密卷以确保数据安全。整个过程确保了磁盘数据的安全性和隐私保护。
667 2
使用SM4算法加密LUKS格式磁盘
|
11月前
|
算法 安全 Go
Go 语言中实现 RSA 加解密、签名验证算法
随着互联网的发展,安全需求日益增长。非对称加密算法RSA成为密码学中的重要代表。本文介绍如何使用Go语言和[forgoer/openssl](https://github.com/forgoer/openssl)库简化RSA加解密操作,包括秘钥生成、加解密及签名验证。该库还支持AES、DES等常用算法,安装简便,代码示例清晰易懂。
292 12
|
2月前
|
XML 前端开发 C#
C#编程实践:解析HTML文档并执行元素匹配
通过上述步骤,可以在C#中有效地解析HTML文档并执行元素匹配。HtmlAgilityPack提供了一个强大而灵活的工具集,可以处理各种HTML解析任务。
184 19
|
3月前
|
监控 算法 C#
C#与Halcon联合编程实现鼠标控制图像缩放、拖动及ROI绘制
C#与Halcon联合编程实现鼠标控制图像缩放、拖动及ROI绘制
542 0
|
C# 开发者
C# 一分钟浅谈:Code Contracts 与契约编程
【10月更文挑战第26天】本文介绍了 C# 中的 Code Contracts,这是一个强大的工具,用于通过契约编程增强代码的健壮性和可维护性。文章从基本概念入手,详细讲解了前置条件、后置条件和对象不变量的使用方法,并通过具体代码示例进行了说明。同时,文章还探讨了常见的问题和易错点,如忘记启用静态检查、过度依赖契约和性能影响,并提供了相应的解决建议。希望读者能通过本文更好地理解和应用 Code Contracts。
253 3
|
11月前
|
存储 安全 编译器
学懂C#编程:属性(Property)的概念定义及使用详解
通过深入理解和使用C#的属性,可以编写更清晰、简洁和高效的代码,为开发高质量的应用程序奠定基础。
845 12
|
设计模式 C# 图形学
Unity 游戏引擎 C# 编程:一分钟浅谈
本文介绍了在 Unity 游戏开发中使用 C# 的基础知识和常见问题。从 `MonoBehavior` 类的基础用法,到变量和属性的管理,再到空引用异常、资源管理和性能优化等常见问题的解决方法。文章还探讨了单例模式、事件系统和数据持久化等高级话题,旨在帮助开发者避免常见错误,提升游戏开发效率。
482 4

热门文章

最新文章

下一篇
oss云网关配置