zoukankan      html  css  js  c++  java
  • 在C#中保存Bouncy Castle生成的密钥对

    用Bouncy Castle的C#版API产生公钥和私钥 中产生了一对密钥对,可以用bouncy caslte提供的API进行保存

    公钥方面的3个类,具体代码根据命名空间自行查看其源代码:

    Org.BouncyCastle.Asn1.X509 . SubjectPublicKeyInfo

    Org.BouncyCastle.X509 . SubjectPublicKeyInfoFactory  

    Org.BouncyCastle.Security . PublicKeyFactory

    用法:

    SubjectPublicKeyInfo subInfo = SubjectPublicKeyInfoFactory .CreateSubjectPublicKeyInfo(rsaPublic);

    //rsaPublic是产生的公钥,类型是AsymmetricKeyParameter/RsaKeyParameters,其中后者集成前者

    AsymmetricKeyParameter testpublicKey = (RsaKeyParameters)PublicKeyFactory. CreateKey(subInfo);

    私钥方面,但私钥保存到本地文件中时,可以选择加密保存,3DES with sha1,涉及到5个类:

    Org.BouncyCastle.Asn1.Pkcs . PrivateKeyInfo

    Org.BouncyCastle.Pkcs . PrivateKeyInfoFactory

    Org.BouncyCastle.Security . PrivateKeyFactory


    Org.BouncyCastle.Asn1.Pkcs . EncryptedPrivateKeyInfo

    Org.BouncyCastle.Pkcs . EncryptedPrivateKeyInfoFactory


    前面3个类的用法同上面公钥的类似

    PrivateKeyInfo privInfo = PrivateKeyInfoFactory .CreatePrivateKeyInfo(rsaPrivate);

    AsymmetricKeyParameter testResult = (RsaPrivateCrtKeyParameters) PrivateKeyFactory .CreateKey(privInfo);


    如果要加密保存私钥的话:

    string alg = "1.2.840.113549.1.12.1.3"; // 3 key triple DES with SHA-1
    byte[] salt = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    int count=1000;
    char[] password="123456".ToCharArray();
    EncryptedPrivateKeyInfo enPrivateKeyInfo = EncryptedPrivateKeyInfoFactory .CreateEncryptedPrivateKeyInfo(
        alg,
        password,
        salt,
        count,
        privateKey);


    EncryptedPrivateKeyInfo 恢复出PrivateKeyInfo 则简单多了:

    PrivateKeyInfo priInfo = PrivateKeyInfoFactory .CreatePrivateKeyInfo(password, enPrivateKeyInfo);

    再导出私钥:

    AsymmetricKeyParameter privateKey = PrivateKeyFactory .CreateKey(priInfo);

    SubjectPublicKeyInfo和PrivateKeyInfo都提供了ToAsn1Object()方法,转换成很Asn1Object,再使用GetEncoded()方法,生成byte数组,然后保存到本地。编码是BER,当然DER也是可以。从本地读取文件时逆过程即可,把读取到的byte数组转换成Asn1Object对象,再使用GetInstance()方法。

    测试代码:

      1 using System;
      2 using System.Collections.Generic;
      3 using System.Collections;
      4 using System.Text;
      5 using System.Security.Cryptography;
      6 using System.Security.Cryptography.X509Certificates;    // X509Certificate2
      7 using System.IO;
      8 using Org.BouncyCastle.Crypto.Generators;
      9 using Org.BouncyCastle.Crypto.Parameters;
     10 using Org.BouncyCastle.Crypto;
     11 using Org.BouncyCastle.Security;
     12 using Org.BouncyCastle.Crypto.Engines;  //IAsymmetricBlockCipher engine = new RsaEngine();
     13 using Org.BouncyCastle.Math;
     14 using Org.BouncyCastle.Asn1.X509; //X509Name
     15 using Org.BouncyCastle.X509;
     16 using Org.BouncyCastle.Utilities.Collections;   //X509V3CertificateGenerator
     17 using Org.BouncyCastle.Asn1.Pkcs;   //PrivateKeyInfo
     18 using Org.BouncyCastle.Pkcs;
     19 using Org.BouncyCastle.Asn1;    
     20  
     21 namespace ConsoleApplication1
     22 {
     23     class Program
     24     { 
     25         static void Main(string[] args)
     26         {
     27             //公钥和密钥的生成,并加密解密测试
     28             RsaKeyGeneratorTest();    //done!!!!!
     29            
     30         }
     31         private static void RsaKeyGeneratorTest()
     32         {
     33             //RSA密钥对的构造器
     34             RsaKeyPairGenerator keyGenerator = new RsaKeyPairGenerator();
     35             //RSA密钥构造器的参数
     36             RsaKeyGenerationParameters param = new RsaKeyGenerationParameters(
     37                 Org.BouncyCastle.Math.BigInteger.ValueOf(3),
     38                 new Org.BouncyCastle.Security.SecureRandom(),
     39                 1024,   //密钥长度
     40                 25);
     41             //用参数初始化密钥构造器
     42             keyGenerator.Init(param);
     43             //产生密钥对
     44             AsymmetricCipherKeyPair keyPair = keyGenerator.GenerateKeyPair();
     45             //获取公钥和私钥
     46             AsymmetricKeyParameter publicKey = keyPair.Public;
     47             AsymmetricKeyParameter privateKey = keyPair.Private;
     48           
     49             if (((RsaKeyParameters)publicKey).Modulus.BitLength < 1024)
     50             {
     51                 Console.WriteLine("failed key generation (1024) length test");
     52             }
     53             savetheKey(publicKey, privateKey);
     54             
     55             
     56             //一个测试……………………
     57             //输入,十六进制的字符串,解码为byte[]
     58             //string input = "4e6f77206973207468652074696d6520666f7220616c6c20676f6f64206d656e";
     59             //byte[] testData = Org.BouncyCastle.Utilities.Encoders.Hex.Decode(input);           
     60             string input = "popozh RSA test";
     61             byte[] testData = Encoding.UTF8.GetBytes(input);
     62             //非对称加密算法,加解密用
     63             IAsymmetricBlockCipher engine = new RsaEngine();
     64             //公钥加密 
     65             //从保存在本地的磁盘文件中读取公钥
     66             Asn1Object aobject = Asn1Object.FromStream(new FileStream(@"E:/Desktop/a.pub",FileMode.Open,FileAccess.Read));  //a.puk??
     67             SubjectPublicKeyInfo pubInfo = SubjectPublicKeyInfo.GetInstance(aobject);
     68             AsymmetricKeyParameter testpublicKey = (RsaKeyParameters)PublicKeyFactory.CreateKey(pubInfo);
     69             FileStream fs;
     70             engine.Init(true, testpublicKey);
     71             try
     72             {
     73                 //Console.WriteLine("加密前:" + Convert.ToBase64String(testData) + Environment.NewLine);
     74                 testData = engine.ProcessBlock(testData, 0, testData.Length);
     75                 Console.WriteLine("加密完成!" + Environment.NewLine);
     76                 fs = new FileStream(@"E:/Desktop/encryptedBytes", FileMode.Create, FileAccess.Write);
     77                 fs.Write(testData, 0, testData.Length);
     78                 fs.Close();
     79                 Console.WriteLine("保存密文成功" + Environment.NewLine);
     80             }
     81             catch (Exception ex)
     82             {
     83                 Console.WriteLine("failed - exception " + Environment.NewLine + ex.ToString());
     84             }
     85             //私钥解密
     86             //获取加密的私钥,进行解密,获得私钥
     87             fs = new FileStream(@"E:/Desktop/encryptedBytes", FileMode.Open, FileAccess.Read);
     88             byte[] anothertestdata = new byte[1024];
     89             fs.Read(anothertestdata, 0, anothertestdata.Length);
     90             fs.Close();
     91             Asn1Object aobj = Asn1Object.FromStream(new FileStream(@"E:/Desktop/a.pri", FileMode.Open, FileAccess.Read));   //a.pvk??
     92             EncryptedPrivateKeyInfo enpri = EncryptedPrivateKeyInfo.GetInstance(aobj);
     93             char[] password = "123456".ToCharArray();
     94             PrivateKeyInfo priKey = PrivateKeyInfoFactory.CreatePrivateKeyInfo(password, enpri);    //解密
     95             AsymmetricKeyParameter anotherprivateKey = PrivateKeyFactory.CreateKey(priKey);    //私钥
     96             engine.Init(false, anotherprivateKey);
     97             try
     98             {
     99                 anothertestdata = engine.ProcessBlock(anothertestdata, 0, testData.Length);
    100                 Console.WriteLine("解密后密文为:" + Encoding.UTF8.GetString(anothertestdata) + Environment.NewLine);
    101             }
    102             catch (Exception e)
    103             {
    104                 Console.WriteLine("failed - exception " + e.ToString());
    105             }
    106             
    107             Console.Read();
    108            
    109         }
    110         private static void savetheKey(AsymmetricKeyParameter publicKey, AsymmetricKeyParameter privateKey)
    111         {
    112             //保存公钥到文件
    113             SubjectPublicKeyInfo publicKeyInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(publicKey);
    114             Asn1Object aobject = publicKeyInfo.ToAsn1Object();
    115             byte[] pubInfoByte = aobject.GetEncoded();
    116             FileStream fs = new FileStream(@"E:/Desktop/a.pub", FileMode.Create, FileAccess.Write);
    117             fs.Write(pubInfoByte, 0, pubInfoByte.Length);
    118             fs.Close();
    119             //保存私钥到文件
    120             /*
    121             PrivateKeyInfo privateKeyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(privateKey);
    122             aobject = privateKeyInfo.ToAsn1Object();
    123             byte[] priInfoByte = aobject.GetEncoded();
    124             fs = new FileStream(@"E:/Desktop/a.pri", FileMode.Create, FileAccess.Write);
    125             fs.Write(priInfoByte, 0, priInfoByte.Length);
    126             fs.Close();
    127             */
    128             string alg = "1.2.840.113549.1.12.1.3"// 3 key triple DES with SHA-1
    129             byte[] salt = { 12345678910 };
    130             int count=1000;
    131             char[] password="123456".ToCharArray();
    132             EncryptedPrivateKeyInfo enPrivateKeyInfo = EncryptedPrivateKeyInfoFactory.CreateEncryptedPrivateKeyInfo(
    133                 alg,
    134                 password,
    135                 salt,
    136                 count,
    137                 privateKey);
    138             byte[] priInfoByte = enPrivateKeyInfo.ToAsn1Object().GetEncoded();
    139             fs = new FileStream(@"E:/Desktop/a.pri", FileMode.Create, FileAccess.Write);
    140             fs.Write(priInfoByte, 0, priInfoByte.Length);
    141             fs.Close();
    142             //还原
    143             //PrivateKeyInfo priInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(password, enPrivateKeyInfo);
    144             //AsymmetricKeyParameter privateKey = PrivateKeyFactory.CreateKey(priInfoByte);
    145          }
    146     }
    147 }
  • 相关阅读:
    【转】#pragma pack(push,1)与#pragma pack(1)的区别
    emwin 之变量定义位置
    【转】C语言字符串与数字相互转换
    【转】用emWin进度条控件做个表盘控件,效果不错
    emwin 之消息 WM_INIT_DIALOG
    emwin 之使用键盘数据发送函数的注意事项
    emwin 解决在A窗口上新建B窗口后‘只激活’B窗口问题
    【转】数学与编程——求余、取模运算及其性质
    hdu4831 Scenic Popularity(线段树)
    2014年百度之星程序设计大赛
  • 原文地址:https://www.cnblogs.com/yasin/p/2746172.html
Copyright © 2011-2022 走看看