web-dev-qa-db-ja.com

BouncyCastleのみを使用してPEMRSA公開鍵を読み取る

C#を使用して、RSA公開鍵のみを含む.pemファイルを読み込もうとしています。私は秘密鍵情報にアクセスできません。また、アプリケーションで秘密鍵情報を必要としません。ファイルmyprivatekey.pemファイルはで始まります

-----BEGIN PUBLIC KEY-----で終わりは-----END PUBLIC KEY-----です。

私の現在のコードは次のとおりです。

    Org.BouncyCastle.Crypto.AsymmetricCipherKeyPair keyPair;

    using (var reader = File.OpenText(@"c:\keys\myprivatekey.pem"))
        keyPair = (Org.BouncyCastle.Crypto.AsymmetricCipherKeyPair)new Org.BouncyCastle.OpenSsl.PemReader(reader).ReadObject();

ただし、コードはメッセージとともにInvalidCastExceptionをスローします

タイプ 'Org.BouncyCastle.Crypto.Parameters.DsaPublicKeyParameters'のオブジェクトをタイプ 'Org.BouncyCastle.Crypto.AsymmetricCipherKeyPair'にキャストできません。

秘密鍵情報が利用できない場合に、BouncyCastleのPemReaderを使用して公開鍵のみを読み取るにはどうすればよいですか?

14
cytinus

次のコードは、ファイル名を指定した場合にのみ公開鍵を読み取ります。例外処理は、すべての製品コードで変更する必要があります。このメソッドはAsymetricKeyParameterを返します。

public Org.BouncyCastle.Crypto.AsymmetricKeyParameter ReadAsymmetricKeyParameter(string pemFilename)
{
    var fileStream = System.IO.File.OpenText (pemFilename);
    var pemReader = new Org.BouncyCastle.OpenSsl.PemReader (fileStream);
    var KeyParameter = (Org.BouncyCastle.Crypto.AsymmetricKeyParameter)pemReader.ReadObject ();
    return KeyParameter;
}
19
cytinus

パブリックPEMファイルとプライベートPEMファイルの両方をRSACryptoServiceProviderに読み込む可能なソリューションは次のとおりです。

public class PemReaderB
{
    public static RSACryptoServiceProvider GetRSAProviderFromPem(String pemstr)
    {
        CspParameters cspParameters = new CspParameters();
        cspParameters.KeyContainerName = "MyKeyContainer";
        RSACryptoServiceProvider rsaKey = new RSACryptoServiceProvider(cspParameters);

        Func<RSACryptoServiceProvider, RsaKeyParameters, RSACryptoServiceProvider> MakePublicRCSP = (RSACryptoServiceProvider rcsp, RsaKeyParameters rkp) =>
        {
            RSAParameters rsaParameters = DotNetUtilities.ToRSAParameters(rkp);
            rcsp.ImportParameters(rsaParameters);
            return rsaKey;
        };

        Func<RSACryptoServiceProvider, RsaPrivateCrtKeyParameters, RSACryptoServiceProvider> MakePrivateRCSP = (RSACryptoServiceProvider rcsp, RsaPrivateCrtKeyParameters rkp) =>
        {
            RSAParameters rsaParameters = DotNetUtilities.ToRSAParameters(rkp);
            rcsp.ImportParameters(rsaParameters);
            return rsaKey;
        };

        PemReader reader = new PemReader(new StringReader(pemstr));
        object kp = reader.ReadObject();

        // If object has Private/Public property, we have a Private PEM
        return (kp.GetType().GetProperty("Private") != null) ? MakePrivateRCSP(rsaKey, (RsaPrivateCrtKeyParameters)(((AsymmetricCipherKeyPair)kp).Private)) : MakePublicRCSP(rsaKey, (RsaKeyParameters)kp);
    }

    public static RSACryptoServiceProvider GetRSAProviderFromPemFile(String pemfile)
    {
        return GetRSAProviderFromPem(File.ReadAllText(pemfile).Trim());
    }
}

これが誰かを助けることを願っています。

10

C0d3Junk13への回答として、PEM秘密鍵について同じ問題が発生し、午後中ずっとC#BouncyCastleバージョン1.7とVisual Studio 2013 DesktopExpressを使用して解決策を見つけるのに時間がかかりました。 BouncyCastle.Crypto.dllへのプロジェクト参照を追加することを忘れないでください

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Collections;
using System.IO;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Asn1.Pkcs;
using Org.BouncyCastle.Crypto.Digests;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Crypto.Signers;
using Org.BouncyCastle.X509;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Math.EC;
using Org.BouncyCastle.Utilities.Collections;
using Org.BouncyCastle.Utilities.Encoders;
using Org.BouncyCastle.Crypto; 
using Org.BouncyCastle.Crypto.Engines; 
using Org.BouncyCastle.OpenSsl;

/* 
    For an Active Directory generated pem, strip out everything in pem file before line:
    "-----BEGIN PRIVATE KEY-----" and re-save.
*/
string privateKeyFileName = @"C:\CertificateTest\CS\bccrypto-net-1.7-bin\private_key3.pem";

TextReader reader = File.OpenText(privateKeyFileName);

Org.BouncyCastle.Crypto.Parameters.RsaPrivateCrtKeyParameters key;

using (reader = File.OpenText(privateKeyFileName))
{
    key = (Org.BouncyCastle.Crypto.Parameters.RsaPrivateCrtKeyParameters)new PemReader(reader).ReadObject();
}

cipher.Init(false, key);

//Decrypting the input bytes

byte[] decipheredBytes = cipher.ProcessBlock(cipheredBytes, 0, cipheredBytes.Length);

MessageBox.Show(Encoding.UTF8.GetString(decipheredBytes));
1
Bertrand_Szoghy

次のコードを試してください。

Using Org.BouncyCastle.Crypto;


string path = HttpContext.Current.Server.MapPath(@"~\key\ABCD.pem");



AsymmetricCipherKeyPair Key;

TextReader tr = new StreamReader(@path);

 PemReader pr = new PemReader(tr);
        Key = (AsymmetricCipherKeyPair)pr.ReadObject();
        pr.Reader.Close();
        tr.Close();



         AsymmetricKeyParameter keaa = Key.Public;
0
Arun Singh

[〜#〜] edit [〜#〜]:これは、使用しているキーファイルの種類によって異なるようです。 ssh-keygenキーの場合、秘密キーのタイプはAsymmetricCipherKeyPairのように見えますが、opensslキーの場合、秘密キーのタイプはRsaPrivateCrtKeyParametersです。


Bryan Jyh Herng Chongの答えは、私にはもううまくいかないようです(少なくともBouncy Castleバージョンv1.8.5では)。 kp.GetType().GetProperty("Private")は、公開鍵と秘密鍵のPEMオブジェクトで異なって設定されなくなったようです。また、PemReader.ReadObject()を使用して返されるオブジェクトは、直接RsaPrivateCrtKeyParametersオブジェクトになっているため、最初にAsymmetricCipherKeyPairオブジェクトをキャストする必要がなくなりました。

私はその行をこれに変更しました、そしてそれは魅力のように働きました:

return (kp.GetType() == typeof(RsaPrivateCrtKeyParameters)) ? MakePrivateRCSP(rsaKey, (RsaPrivateCrtKeyParameters)kp)) : MakePublicRCSP(rsaKey, (RsaKeyParameters)kp);
0
jzfizzler