【问题标题】:C# BouncyCastle PKCS#8C# BouncyCastle PKCS#8
【发布时间】:2020-07-29 04:33:36
【问题描述】:

我想使用 .net 框架(不是 .netcore)加载 PEM

-----BEGIN ENCRYPTED PRIVATE KEY-----
MIHs........................................................CAAw
DAYI........................................................gZAf
Y/Iu........................................................X7DZ
ZKoE........................................................OYQQ
3ZST........................................................A2E=
-----END ENCRYPTED PRIVATE KEY-----
  • 我尝试在 BouncyCastle 中使用以下代码,但它会抛出 PemException: “创建加密私钥时出现问题:Org.BouncyCastle.Crypto.InvalidCipherTextException:垫块损坏”
 class Passowrd : IPasswordFinder
    {
        private string v;

        public Passowrd(string v)
        {
            this.v = v;
        }

        public char[] GetPassword()
        {
            return v.ToCharArray();
        }
    }

var pemReader = new PemReader(new StringReader(privateKeyText), new Passowrd("PASSWORD"));
var pemObj = pemReader.ReadObject(); // this line throw PemException
  • 但是,我使用 .netcore3.1 通过以下代码加载完全相同的 PEM 文件:
    var ecdsa = ECDsa.Create();
    ecdsa.ImportEncryptedPkcs8PrivateKey(passSpan, privateKeyBytes, out _);

【问题讨论】:

  • 嗯,我无法在 .NET Framework 4.7.2 上重现该问题。此错误消息是例如如果密码不正确或IPasswordFinder 实现有错误,则会显示。请发布您的Passowrd-Implementation。
  • 感谢您的帮助,我已经添加了密码实现。
  • 该代码适用于我(.NET Framework 4.7.2)。可能是密码打错了?您使用的是哪个 .NET Framework 版本?
  • 密码肯定是正确的,我在 .netcore 代码中使用了完全相同的密码并且它可以工作。你用的是什么版本的“充气城堡”?我正在使用
  • 我使用的是 1.8.5。如果发布的密钥的密码确实是 PASSWORD,那么我可以重现该问题。然后这个特定键似乎存在问题,因为它可以使用其他键。我去看看钥匙。

标签: c# bouncycastle ecdsa pkcs#8


【解决方案1】:

您可以使用

读取 PEM
var pemReader = new Org.BouncyCastle.OpenSsl.PemReader(new StringReader(privateKeyText), new Passowrd("PASSWORD"));

var pemReader = new Org.BouncyCastle.Utilities.IO.Pem.PemReader(new StringReader(privateKeyText));

然后阅读类似的内容

var pemObject = pemReader.ReadPemObject();

【讨论】:

  • 但是 ReadPemObject 不返回 KeyPair.... 换句话说,我想要: AsymmetricCipherKeyPair KeyPair = (AsymmetricCipherKeyPair)pemObject .ReadObject();
【解决方案2】:

问题似乎与密钥的加密有关:如果在密钥加密时未设置选项-v2prf hmacWithSHA1,则无法使用PemReader 读取密钥。

-v2prf 选项自 V1.1.0 起就存在,并指定与 PKCS#5 v2.0 或密钥派生函数 PBKDF2 一起使用的 PRF(伪随机函数)算法。

  • 案例 1:创建新密钥

以下两条语句创建并加密密钥:

    openssl ecparam -name secp256r1 -genkey -noout -out <out-path>
    openssl pkcs8 -topk8 -v2 aes256 -v2prf hmacWithSHA1 -in <in-path> -out <out-path>  // aes256 as of OpenSSL 1.1.0 inclusive

以这种方式生成的密钥可以使用PemReader 成功读取。但是,如果缺少选项-v2prf hmacWithSHA1,则会引发异常。

  • 案例 2:修复已生成的密钥

以下语句解密已加密的密钥:

    openssl pkcs8 -topk8 -nocrypt -in <in-path> -out <out-path>

如果密钥随后使用-v2prf hmacWithSHA1 选项集(见上文)加密,则可以使用PemReader 成功读取密钥。 通过这种方式,我能够修复发布的密钥,以便可以使用 PemReader 读取它!

可以在openssl pkcs8 的文档中找到一个可能的(不幸的是只是肤浅的)解释。在那里可以阅读-v2prf 选项:

某些实现可能不支持自定义 PRF 算法,可能需要 hmacWithSHA1 选项才能工作。

有趣的是,使用 .NET Core 3.x 中的 ECDsa#ImportEncryptedPkcs8PrivateKey 可以毫无问题地读取关键密钥。要获得完整的解释,可能需要查看源代码。

【讨论】:

    猜你喜欢
    • 2011-03-16
    • 1970-01-01
    • 2017-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-04
    • 2023-03-20
    相关资源
    最近更新 更多