【问题标题】:Bouncy Castle, RSA: transforming keys into a String formatBouncy Castle,RSA:将密钥转换为字符串格式
【发布时间】:2011-07-02 17:09:50
【问题描述】:

我在我的 C# 项目中使用 RSA(Bouncy Castle API)。我用这种方法生成了密钥对:

RsaKeyPairGenerator r = new RsaKeyPairGenerator();
r.Init(new KeyGenerationParameters(new SecureRandom(), 1024));
AsymmetricCipherKeyPair keys = r.GenerateKeyPair();

AsymmetricKeyParameter private_key = keys.Private;
AsymmetricKeyParameter public_key = keys.Public;

现在我想将它们保存在 txt 文件中,但问题是我无法将它们转换为字符串格式。我在另一篇文章中读到,密钥必须使用以下方法序列化:

PrivateKeyInfo k = PrivateKeyInfoFactory.CreatePrivateKeyInfo(private_key);
byte[] serializedKey = k.ToAsn1Object().GetDerEncoded();

这是正确的方法吗?如果是,在此之后我应该怎么做?只需将它们从 byte[] 转换为 String 即可?

【问题讨论】:

    标签: c# rsa bouncycastle


    【解决方案1】:

    您也可以使用 PemWriter 以 PEM 格式存储它们:

    TextWriter textWriter = new StringWriter();
    PemWriter pemWriter = new PemWriter(textWriter);
    pemWriter.WriteObject(keys.Private);
    pemWriter.Writer.Flush();
    
    string privateKey = textWriter.ToString();
    

    现在 privateKey 包含如下内容:

    -----BEGIN RSA PRIVATE KEY-----
    MIICXQIBAAKBgQDFhB3xI1AzSMsKvt7rZ7gp2o/vd49zON89iL1ENvKkph7oFXa2
    ew/hjzbAV33lHnFFlA/vA5SDCbggRyU1/SmjfuPJFEzFbgcPLuO1Sw6z+bWXiIFp
    QNCOTIw11c0fbwk+kB2y4E1OkLv5f9atlNlekb4wBn8bMbFYtu6LGWjkFQIDAQAB
    AoGANPoMteLM3hSGMSmkzOsS4Fb5CDe/SB5W8kA805ERX8wWuhUXtDYpukwZWVme
    MNgLdagS5f7F1KfEtROgDW0Lv4/T/FWAbpgh8O2CPKYDY4ZXl8tmRH9dtYn/824l
    veLxdgNjHwo5OMvuTSDMjC3tbg2UA3kmV4VAm5QotlRinUECQQDo4zvI5e81zWnS
    kNrUARX80t432MOZyr0RvAaVJfBNQpJl0H0xp5LKP74hvPVO9WdJvJ0M4Z4QrmGO
    bm2Hsfz5AkEA2R469YXxgPLDg/LvUQqfrl8Ji9+rip7eQP7iS/dt66NMS31/HymT
    +HscEZ3qGlnQuyyyRR2rGQdhdjU42HNy/QJBAKbPTF1DxSmGbovyUauU84jaCW17
    B++6dd6kDRr7x7mvO2lOAr50RwIy0h8cV6EsycTZIqy9VhigryP0GOQfKxECQA8T
    uVZpab7hnNAh45qGGVabhOcwrhHfPGHZEU/jK7/sRBUN7vD0CzF7IxTaGXKhAAyv
    auW/zKzdRVhXE858HeUCQQCGaaAg8GwM0qIS0nHRTLldu4hIGjKn7Sk0Z46Plfwr
    oqPCtuP4ehX85EIhqCcoFnG6Ttr6AxSgNMZvErVxDBiD
    -----END RSA PRIVATE KEY-----
    

    【讨论】:

    • 这个答案是正确的,只是改最后一行,而不是string privateKey = pemWriter.ToString();试试string privateKey = textWriter.ToString();
    【解决方案2】:

    好吧,我不知道 RSA 特定的一面,但是一旦你有一个不透明的二进制字符串(即它可以包含任何任意数据),文本转换的最佳选择是 Convert.ToBase64String(byte[]),你可以反转它Convert.FromBase64String(string)

    不要为此使用Encoding.GetString(byte[])Encoding.GetBytes(string) - 二进制数据不是特定编码的文本,不应被视为这样.如果您尝试这样做,您几乎肯定会丢失数据。

    【讨论】:

    • 感谢您的快速回答。我按照你说的做了,结果我得到了这个 MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAJ7s/B4XNHmNa9LwZ91z... 我认为它应该是 BigInteger 不?因为在 RSA 中我们使用数字 (p, q ...)
    • 方法名(GetDerEncoded)表明返回的数据包含DER编码格式的所有RSA密钥参数(p、q、...)。
    • @Rami:您的目标是让您可以“再水化”回 PrivateKeyInfo 的东西吗?如果是这样,你不需要知道整数等......你只是想确保你可以序列化为一个字节数组(然后是一个字符串),反之亦然。
    • @Christian 谢谢,所以我将所有参数都恢复为一种格式。很酷,但是我如何划分它以获得(p,q ...)的值?有什么方法吗?再次感谢。
    • @Rami:查看 Bouncy Castle API 文档的其余部分,了解对 GetDerEncoded 和 ToAsn1Object 的反向操作。
    【解决方案3】:
    【解决方案4】:

    试试下面的

            RsaKeyPairGenerator rsaKeyPairGenerator = new RsaKeyPairGenerator();
            rsaKeyPairGenerator.Init(new KeyGenerationParameters(new SecureRandom(), XXX));
    
            AsymmetricCipherKeyPair keys = rsaKeyPairGenerator.GenerateKeyPair();
    
            PrivateKeyInfo privateKeyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(keys.Private);
            // Write out an RSA private key with it's asscociated information as described in PKCS8.
            byte[] serializedPrivateBytes = privateKeyInfo.ToAsn1Object().GetDerEncoded();
            // Convert to Base64 ..
            string serializedPrivateString = Convert.ToBase64String(serializedPrivateBytes);
    
            SubjectPublicKeyInfo publicKeyInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(keys.Public);
            byte[] serializedPublicBytes = publicKeyInfo.ToAsn1Object().GetDerEncoded();
            string serializedPublicString = Convert.ToBase64String(serializedPublicBytes);
    

    【讨论】:

      【解决方案5】:

      如果您将 bouncycastle 证书转换为 .net 证书。执行此操作的函数在 bouncycastle 库中(我相信它在一个名为 DotNetUtilities 的类中)。 RSACryptoServiceProvider 有一个功能:

      ToXmlString(bool includePrivateKey). 
      

      如果您想要包含单独序列化为 base64 的所有组件、指数、模数和 d(私有指数)的私钥,这将为您提供证书的 x 表示。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-03-16
        • 2018-08-15
        • 1970-01-01
        • 2015-11-15
        • 2014-02-06
        • 2010-11-03
        • 1970-01-01
        相关资源
        最近更新 更多