クライアントなどを追跡するための証明書配布システムを作成しています。
何が起こるか:
- クライアントが CSR をサーバーに送信する
- サーバーは証明書をチェックして署名します
- サーバーは署名付き証明書をクライアントに送信します
- クライアントは署名付き証明書と秘密鍵を Windows ストアに置きます。
したがって、クライアントでは次のことが起こります。
//Pseudo Server Object:
Server s = new Server();
//Requested Certificate Name and things
X509Name name = new X509Name("CN=Client Cert, C=NL");
//Key generation 2048bits
RsaKeyPairGenerator rkpg = new RsaKeyPairGenerator();
rkpg.Init(new KeyGenerationParameters(new SecureRandom(), 2048));
AsymmetricCipherKeyPair ackp = rkpg.GenerateKeyPair();
//PKCS #10 Certificate Signing Request
Pkcs10CertificationRequest csr = new Pkcs10CertificationRequest("SHA1WITHRSA", name, ackp.Public, null, ackp.Private);
//Make it a nice PEM thingie
StringBuilder sb = new StringBuilder();
PemWriter pemwrit = new PemWriter(new StringWriter(b));
pemwrit.WriteObject(csr);
pemwrit.Writer.Flush();
s.SendRequest(sb.ToSting());
わかりましたので、サーバーサイドをスキップします。サーバーが証明書に署名してクライアントに送り返すことを信じてください。それが私が行動を起こすところです。
PemReader pr = new PemReader(new StringReader(b.ToString()));
X509Certificate cert = (X509Certificate)pr.ReadObject();
//So lets asume I saved the AsymmetricCipherKeyPair (ackp) from before
//I have now the certificate and my private key;
//first I make it a "Microsoft" x509cert.
//This however does not have a PrivateKey thats in the AsymmetricCipherKeyPair (ackp)
System.Security.Cryptography.X509Certificates.X509Certificate2 netcert = DotNetUtilities.ToX509Certificate(cert);
//So here comes the RSACryptoServerProvider:
System.Security.Cryptography.RSACryptoServiceProvider rcsp = new System.Security.Cryptography.RSACryptoServiceProvider();
//And the privateKeyParameters
System.Security.Cryptography.RSAParameters parms = new System.Security.Cryptography.RSAParameters();
//now I have to translate ackp.PrivateKey to parms;
RsaPrivateCrtKeyParameters BCKeyParms = ((RsaPrivateCrtKeyParameters)ackp1.Private);
//D is the private exponent
parms.Modulus = BCKeyParms.Modulus.ToByteArray();
parms.P = BCKeyParms.P.ToByteArray();
parms.Q = BCKeyParms.Q.ToByteArray();
parms.DP = BCKeyParms.DP.ToByteArray();
parms.DQ = BCKeyParms.DQ.ToByteArray();
parms.InverseQ = BCKeyParms.QInv.ToByteArray();
parms.D = BCKeyParms.Exponent.ToByteArray();
parms.Exponent = BCKeyParms.PublicExponent.ToByteArray();
//Now I should be able to import the RSAParameters into the RSACryptoServiceProvider
rcsp.ImportParameters(parms);
//<em><b>not really</b></em> This breaks says "Bad Data" and not much more. I'll Post the
//stacktrace at the end
//I open up the windows cert store because thats where I want to save it.
//Add it and save it this works fine without the privkey.
X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
store.Open(OpenFlags.MaxAllowed);
store.Add(netcert);
store.Close();
おそらく、サーバー側で何か問題が発生しているに違いないと考えているでしょう。まあそれは私も思ったことですが、この証明書からpfxファイルを作成し、手動でインポートするとうまくいきました....
どういうわけか、.NET RSA 秘密鍵と BouncyCastle RSA 秘密鍵との間に違いがあり、私はそれを指で示すことができません。
おそらく、pfx をインポートしてから、X509Store 経由でそこから秘密鍵を取得することをお勧めします。私は試した。:S そして失敗しました。ExportParameters(true)
プライベートパラメーターを含めることの真の意味を理解しようとするとすぐに。「指定された状態での使用には有効なキーではありません。」と表示されます。最後に完全な例外を参照してください。
この豚を以前に殺したことがあるか、私を助けてくれる人がいるといいのですが。
***Exceptions:***
System.Security.Cryptography.CryptographicException was unhandled
Message="Key not valid for use in specified state.\r\n"
Source="mscorlib"
StackTrace:
at System.Security.Cryptography.CryptographicException.ThrowCryptogaphicException(Int32 hr)
at System.Security.Cryptography.Utils._ExportKey(SafeKeyHandle hKey, Int32 blobType, Object cspObject)
at System.Security.Cryptography.RSACryptoServiceProvider.ExportParameters(Boolean includePrivateParameters)
InnerException:
***And the other one:***
System.Security.Cryptography.CryptographicException was unhandled
Message="Bad Data.\r\n"
Source="mscorlib"
StackTrace:
at System.Security.Cryptography.CryptographicException.ThrowCryptogaphicException(Int32 hr)
at System.Security.Cryptography.Utils._ImportKey(SafeProvHandle hCSP, Int32 keyNumber, CspProviderFlags flags, Object cspObject, SafeKeyHandle& hKey)
at System.Security.Cryptography.RSACryptoServiceProvider.ImportParameters(RSAParameters parameters)
InnerException: