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


    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平台解析,(CFcompact framework

     

    u       使用BigInteger类进行公钥解密

    pem文件的解析

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

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

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

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

    internal AsnKeyParser(AsnParser parser)

    {

    this.parser = parser;

    }

    private AsnParser parser;

    //AsnParserAsnKeyParser.cs文件中的一个类)。

     

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

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

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

    AsnParser parser = new AsnParser(binKey);

    AsnKeyParser keyParser = new AsnKeyParser(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 = new BigInteger(publicKey.Modulus);

    BigInteger biE = new BigInteger(publicKey.Exponent);

    BigInteger biText = new BigInteger(data);

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

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

     

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

    private static byte[] HexStringToByteArray(string sBytes)

    {

    int pos = 0;

    int len = (sBytes.Length / 2);

    byte[] b = new byte[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,如果是第234字节是00的话,修改BigInteger中的getBytes方法便可解决,修改如下:

    public byte[] getBytes()

    {

    int numBits = bitCount();

     

    int numBytes = numBits >> 3;

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

    numBytes++;

     

    byte[] result = new byte[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\bzip2csharp\crypto\src两个文件夹所有的内容

    然后删除crypto\src\ AssemblyInfo.cscrypto\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 = new StreamReader("c:/pub.key");

     

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

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

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

    CMpgg9jDGmGwdp4mg5LopYag0ZYHq21AJwIDAQAB

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

     

    PemReader y1 = new PemReader(xl);

     

    string sign = "mt25lD1UX9fnf+96v1Y8hlvIgW0Uou3H7LivTeiQaSoXFNzHaBntuFz2NDIe7XGF";

     

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

     

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

     

    IAsymmetricBlockCipher engine = new RsaEngine();

    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 = new StreamReader(appPath+"\\pub.key");

    PemReader y1 = new PemReader(xl);

     

    string sign = "mt25lD1UX9fnf+96v1Y8hlvIgW0Uou3H7LivTeiQaSoXFNzHaBntuFz2NDIe7XGF";

     

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

    PemObject ss1=y1.ReadPemObject();

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

    IAsymmetricBlockCipher engine = new RsaEngine();

    engine.Init(false, pubkey);

     

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

     

    string temp = byteToHexStr(testData);

     

     

  • 相关阅读:
    白话https
    网络分层体系结构
    软件度量
    【Java】itext根据模板生成pdf(包括图片和表格)
    【java】Freemarker 动态生成word(带图片表格)
    压力测试-接口关联
    压力测试-录制脚本
    jmeter性能测试2:基础功能介绍
    jmeter性能测试1:目录解析
    桃花运
  • 原文地址:https://www.cnblogs.com/yuxuan/p/2200672.html
Copyright © 2020-2023  润新知