RSA加解密使用总结,.net私钥加密公钥解密,WinCE平台RSA加解密

9 篇文章 0 订阅
5 篇文章 0 订阅

BouncyCastle.Crypto.dll

该库的源代码下载地址:http://www.bouncycastle.org/csharp/download/bccrypto-net-1.7-src.zip

 

BigInteger类具有RSA加解密的功能,下载地址:

http://www.codeproject.com/KB/cs/biginteger.aspx

 

对pem密钥文件的解析参考代码:

http://www.codeproject.com/KB/security/CryptoInteropKeys.aspx 


 ————————————————————————————————————————————————

使用pem格式RSA密钥文件加解密,大致从两个方面介绍

一、对RSA文件格式的解析

a)        RSA文件的生成(openssl的使用方法)

b)       RSA文件在不同平台中的解析方式(解析代码)

二、对解析出来的公钥,私钥的使用方法

a)        Java平台上的不同的加解密方式(公钥加密,私钥解密/私钥加密,公钥解密)

b)       .net平台上的不同的加解密方式(私钥加密,公钥解密/公钥加密,私钥解密)

从根本上解决不同平台RSA密钥互通的问题。

 

.net平台pem文件解析方式:NF上解析,CF平台解析,(CF:compactframework)

 

u      使用BigInteger类进行公钥解密

pem文件的解析

对pem密钥文件的解析参考代码:

http://www.codeproject.com/KB/security/CryptoInteropKeys.aspx

为了使该代码可以在CF平台上也能使用,对其做了一些修改。

首先为了方便解析pem文件,在AsnKeyParser类中添加了一个构造函数,和一个变量。(类本身提供了一个internal AsnKeyParser(Stringpathname)方法用来解析pem文件。)

internal AsnKeyParser(AsnParserparser)

{

this.parser = parser;

}

private AsnParserparser;

//(AsnParser是AsnKeyParser.cs文件中的一个类)。

 

然后是从公钥字符串中获取公钥的代码:

byte[] binKey = System.Convert.FromBase64String(pub_key); 

// Base64解码,pub_key是公钥字符串

AsnParser parser = newAsnParser(binKey);

AsnKeyParser keyParser = newAsnKeyParser(parser);

RSAParameters publicKey =keyParser.ParseRSAPublicKey();

//至此为止获得了公钥

使用BigInteger类作公钥解密

由于.net平台上提供的RSACryptoServiceProvider只能用作公钥加密,私钥解密,(和其内部实现有关)。如果要使用私钥加密,公钥解密,可以依靠第三方,使用标准RSA算法实现的组件。

以上所提到的BigIngeter类提供了标准的RSA加解密算法,

BigInteger类具有解密的功能,下载地址:

http://www.codeproject.com/KB/cs/biginteger.aspx

 

使用公钥解密的具体方法如下:

byte[] data = Convert.FromBase64String(enStr);//enStr为密文

//byte[] data =HexStringToByteArray(enStr);

//如果密文是16进制字符串可以使用HexStringToByteArray方法转换为字节数组

 

BigInteger biN = newBigInteger(publicKey.Modulus);

BigInteger biE = newBigInteger(publicKey.Exponent);

BigInteger biText = newBigInteger(data);

BigInteger biEnText = biText.modPow(biE, biN);

string temp =byteToHexStr(biEnText.getBytes());

 

//十六进制字符串转为byte数组

private static byte[] HexStringToByteArray(stringsBytes)

{

int pos = 0;

int len = (sBytes.Length / 2);

byte[] b = newbyte[len];

int count = sBytes.Length;

 

for (int i= 0; i < count; i += 2)

{

b[pos] = Convert.ToByte(sBytes.Substring(i,2), 16);

pos++;

}

 

//string temp =Encoding.Default.GetString(b);

return b;

}

 

/// <summary>

/// 字节数组转16进制字符串

/// </summary>

/// <param name="bytes"></param>

/// <returns></returns>

public static string byteToHexStr(byte[]bytes)

{

string returnStr = "";

if (bytes != null)

{

for (int i= 0; i < bytes.Length; i++)

{

returnStr += bytes[i].ToString("X2");

}

}

return returnStr;

}

 

由于我的原文是16进制的字符串,在解密的过程中发现如果原文的字节中有00的话解密会有异常,原文第一字节如果是00,解密出来会被抛弃,只要手工加上00,如果是第2,3,4字节是00的话,修改BigInteger中的getBytes方法便可解决,修改如下:

public byte[] getBytes()

{

int numBits = bitCount();

 

int numBytes = numBits >> 3;

if ((numBits & 0x7) != 0)

numBytes++;

 

byte[] result = newbyte[numBytes];

 

//Console.WriteLine(result.Length);

 

int pos = 0;

uint tempVal, val = data[dataLength - 1];

 

if ((tempVal = (val >> 24 &0xFF)) != 0)

{ result[pos++] = (byte)tempVal; }

 

if ((tempVal = (val >> 16 &0xFF)) != 0)

{ result[pos++] = (byte)tempVal; }

else if (pos> 0)

{ pos++; }

else

{ result[pos++] = (byte)tempVal; }

 

if ((tempVal = (val >> 8 &0xFF)) != 0)

{ result[pos++] = (byte)tempVal; }

else if (pos> 0)

{ pos++; }

else

{ result[pos++] = (byte)tempVal; }

 

if ((tempVal = (val & 0xFF)) != 0)

{ result[pos++] = (byte)tempVal; }

else

{ result[pos++] = (byte)tempVal; }

 

for (int i= dataLength - 2; i >= 0; i--, pos += 4)

{

val = data[i];

result[pos + 3] = (byte)(val & 0xFF);

val >>= 8;

result[pos + 2] = (byte)(val & 0xFF);

val >>= 8;

result[pos + 1] = (byte)(val & 0xFF);

val >>= 8;

result[pos] = (byte)(val& 0xFF);

}

 

return result;

}

 

u      使用开源的BouncyCastle.Crypto.dl组件库来作加解密

该库的源代码下载地址:http://www.bouncycastle.org/csharp/download/bccrypto-net-1.7-src.zip

       使用时,先导入其中crypto\bzip2,csharp\crypto\src两个文件夹所有的内容

然后删除crypto\src\ AssemblyInfo.cs,crypto\src\asn1\util\ Dump.cs文件

 

crypto\src\util\Platform.cs类中编写了平台与编译选择代码,如果要在WinCE平台(CF)上使用,需要在条件预编译中加上条件编译,右键点击项目》属性

在条件编译符号在加上:NETCF_2_0,

对平台的支持情况,可以参看crypto\src\util\ Platform.cs类中的条件预编译代码

 

对于WinForm中可以直接使用BouncyCastle.Crypto.dl库

下载地址:http://www.bouncycastle.org/csharp/download/bccrypto-net-1.7-bin.zip

 

调用的代码如下:(还是使用公钥解密密文)

using System.Security.Cryptography;

 

using Org.BouncyCastle.Crypto.Generators;

using Org.BouncyCastle.Crypto.Parameters;

using Org.BouncyCastle.Crypto;

using Org.BouncyCastle.Security;

using Org.BouncyCastle.Crypto.Engines;

 

using Org.BouncyCastle.OpenSsl;

 

TextReader xl = newStreamReader("c:/pub.key");

 

//pub.key文件格式如下:

-----BEGIN PUBLIC KEY-----

MEwwDQasdf…………………Y6oTv3w1hq+zSCzcw6Mv+a6Kx3

CMpgg9jDGmGwdp4mg5LopYag0ZYHq21AJwIDAQAB

-----END PUBLIC KEY-----

 

PemReader y1 = newPemReader(xl);

 

string sign = "mt25lD1UX9fnf+96v1Y8hlvIgW0Uou3H7LivTeiQaSoXFNzHaBntuFz2NDIe7XGF";

 

byte[] data = System.Convert.FromBase64String(sign);

 

AsymmetricKeyParameter pubkey = (AsymmetricKeyParameter)y1.ReadObject();

 

IAsymmetricBlockCipher engine = newRsaEngine();

engine.Init(false,pubkey);

 

byte[] testData = engine.ProcessBlock(data,0, data.Length);

 

string temp = byteToHexStr(testData); //字节数组转换为16进制字符串

 

在CE平台调用上有些差异,调用方法如下:

string appPath = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.FullyQualifiedName);

TextReader xl = newStreamReader(appPath+"\\pub.key");

PemReader y1 = newPemReader(xl);

 

string sign = "mt25lD1UX9fnf+96v1Y8hlvIgW0Uou3H7LivTeiQaSoXFNzHaBntuFz2NDIe7XGF";

 

byte[] data = System.Convert.FromBase64String(sign);

PemObject ss1=y1.ReadPemObject();

AsymmetricKeyParameter pubkey = PublicKeyFactory.CreateKey(ss1.Content);

IAsymmetricBlockCipher engine = newRsaEngine();

engine.Init(false,pubkey);

 

byte[] testData = engine.ProcessBlock(data,0, data.Length);

 

string temp = byteToHexStr(testData);

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值