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#实现的更多相关文章

  1. 银联手机支付(.Net Csharp),3DES加密解密,RSA加密解密,RSA私钥加密公钥解密,.Net RSA 3DES C#

    前段时间做的银联支付,折腾了好久,拼凑的一些代码,有需要的朋友可以参考,本人.Net新手,不保证准确性! 这个银联手机支付没有SDK提供,技术支持也没有.Net的,真心不好搞! RSA加解密,这里有个 ...

  2. RSA不对称加密,公钥加密私钥解密,私钥加密公钥解密

    RSA算法是第一个能同时用于加密和数字签名的算法,也易于理解和操作. RSA是被研究得最广泛的公钥算法,从提出到现在已近二十年,经历了各种攻击的考验,逐渐为人们接受,普遍认为是目前最优秀的公钥方案之一 ...

  3. RSA 加密算法 Java 公钥加密私钥解密 和 私钥加密公钥解密 的特点

    package com.smt.cipher.unsymmetry; import org.apache.commons.codec.binary.Base64; import org.apache. ...

  4. 求求你们不要再用 RSA 私钥加密公钥解密了,这非常不安全!

    最近经常在网上看到有人说巨硬的 CNG(Cryptography Next Generation 即下一代加密技术) 只提供 RSA 公钥加密私钥解密,没有提供 RSA 私钥加密公钥解密,他们要自己封 ...

  5. golang 私钥"加密"公钥"解密"

    ---恢复内容开始---   之前工作主要使用C/C++与银行/第三方支付对接,但C/C++无法满足客户"当天给协议明天实盘上载"的开发速度以及现公司一些特殊情况,所以决定用go来 ...

  6. C# 基于大整数类的RSA算法实现(公钥加密私钥解密,私钥加密公钥解密)

    但是C#自带的RSA算法类RSACryptoServiceProvider只支持公钥加密私钥解密,即数字证书的使用. 所以参考了一些网上的资料写了一个RSA的算法实现.算法实现是基于网上提供的一个大整 ...

  7. RSA公钥加密-私钥解密/私钥加密-公钥解密

    package com.tebon.ams.util;import org.apache.commons.codec.binary.Base64;import org.apache.log4j.Log ...

  8. NetCore 生成RSA公私钥对,公钥加密私钥解密,私钥加密公钥解密

    using Newtonsoft.Json; using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto.Encodings; using ...

  9. RSA加解密 私钥加密公钥解密 私加公解 && C++ 调用openssl库 的代码实例

    前提:秘钥长度=1024 ============================================== 对一片(117字节)明文加密  私加 ===================== ...

随机推荐

  1. 让 PowerDesigner 支持 SQLite!

    让 PowerDesigner 支持 SQLite!   PowerDesigner是一个功能强大的数据库设计软件,最近正在用其设计新系统的数据库,但由于在项目初级阶段,希望使用轻量级的 SQLite ...

  2. LoadRunner界面分析(二)

    1.Controller 2.创建运行场景 3.方案设计 4.Resuls settting 5.监视方案

  3. 淘宝API开发(三)

    自动登录到淘宝定时获取订单: C#控制台程序 第一步,获得淘宝真实登录地址.淘宝授权地址(https://oauth.taobao.com/authorize?response_type=token& ...

  4. CListCtrl总结.xml

    pre{ line-height:1; color:#d1653c; background-color:#000000; font-size:16px;}.sysFunc{color:#566d68; ...

  5. C++抽象机制之二:运算符重载

    1.二元运算符aa@bb,可以定义为 1).一个参数的非静态成员函数:aa.operator@(bb);  (成员函数有this指针) 2). 两个参数的非成员函数:operator@(aa,bb); ...

  6. Tcl之load

    做一个ASIC项目,基本结构是MCU+ROM+RAM.目前想把单片机程序下载到ROM中,然后在ModelSim中仿真程序,得到运行结果.好二哥给出的Tcl下载文件如下,细细研读中... puts &q ...

  7. HUE 安装

    1.从github网下载hue-master.zip (源代码包) 地址:https://github.com/cloudera/hue#development-prerequisites 2.安装依 ...

  8. 耳机jack构造及在应用时可能出现的问题

    目前市场上耳机分为4环耳机(图1所示,iphone型)和3环耳机(图2所示).4环耳机称为headset,3环耳机称为headphone,两者之间的区别就是4环耳机比3环耳机多个micphone.而J ...

  9. Java多线程之 ThreadLocal

    一.什么是ThreadLocal? 顾名思义它是local variable(线程局部变量).它的功用非常简单,就是为每一个使用该变量的线程都提供一个变量值的副本,是每一个线程都可以独立地改变自己的副 ...

  10. HD2144Calculate S(n)

    Problem Description Calculate S(n). S(n)=13+23 +33 +......+n3 . Input Each line will contain one int ...