2016-11-07 15 views
0

ストアからの証明書に問題があります。私のアプリでは、ユーザーはファイルの証明書やストアの証明書を使用できます。証明書を読み込んだ後、私は署名データの証明書を使用します。RSACryptoServiceProviderのストアからの証明書を使用

ファイルからの証明書の使用は問題ありませんが、同等の使用はできません。看板用

コード:ファイルからの読み込みのための証明書

// Sign data 
using (RSACryptoServiceProvider csp = new RSACryptoServiceProvider()) 
{ 
    byte[] dataToSign = Encoding.UTF8.GetBytes(plainText); 
    csp.ImportParameters(((RSACryptoServiceProvider)_certPopl.PrivateKey).ExportParameters(true)); 
    byte[] signature = csp.SignData(dataToSign, "SHA256"); 
    // Verify signature 
    if (!csp.VerifyData(dataToSign, "SHA256", signature)) 
     throw new Exception("Nepodařilo se vytvořit platný podpisový kód poplatníka."); 
    PKP = Convert.ToBase64String(signature); 
} 

コード:店舗からの読み出し証明書の

X509Certificate2Collection certStore = new X509Certificate2Collection(); 
certStore.Import(fileName, password, X509KeyStorageFlags.Exportable); 
foreach (X509Certificate2 cert in certStore) 
{ 
    // Find the first certificate with a private key 
    if (cert.HasPrivateKey) 
    { 
     _certPopl = cert; 
     break; 
    } 
} 

コード。ストアからの負荷証明書の後、私はデータに署名できません:

public void LoadCertificate(string certificateName, DateTime notAfter, string password) 
{ 
    var store = new X509Store(StoreName.My, StoreLocation.CurrentUser); 
    store.Open(OpenFlags.MaxAllowed); 
    foreach (var certificate in store.Certificates) 
    { 
     if (certificate.FriendlyName.Equals(certificateName) && certificate.NotAfter.Equals(notAfter)) 
     { 
      //X509Certificate2Collection certStore = new X509Certificate2Collection(); 
      //certStore.Import(certificate.Export(X509ContentType.SerializedCert), password, X509KeyStorageFlags.Exportable); 
      //_certPopl = certStore[0]; 

      X509Certificate2Collection certStore = new X509Certificate2Collection(); 
      certStore.Import(certificate.GetRawCertData()); 
      foreach (X509Certificate2 cert in certStore) 
      { 
       // Find the first certificate with a private key 
       if (cert.HasPrivateKey) 
       { 
        _certPopl = cert; 
        break; 
       } 
      } 

      break; 
     } 
    } 
} 

私は証明書の使用経験はありません。しかし、私は署名のために店舗から証明書を取得するのと同等のものが必要です。

ExportParametersでSystem.Security.Cryptography.CryptographicExceptionがスローされます(true)。 例外の追加情報:指定された状態で使用するための鍵は無効です。

ありがとうございました。

+0

'私はdata'に署名することができません - これは私たちに役立つ何かを言うことはありません。エラーを発生させるエラーメッセージとコードが役立つでしょう。 – Crypt32

+0

例外に関する情報を追加:ExportParametersでSystem.Security.Cryptography.CryptographicExceptionがスローされます(true)。例外の追加情報:指定された状態で使用するためのキーは無効です。 –

答えて

0

CSPパラメータをエクスポートしようとしている理由がわかりません。 CSPパラメータのエクスポートはキーのエクスポートオプションに依存し、キーがエクスポートできない場合は失敗します。店舗から

ロード証明書:

// assuming, you have X509Certificate2 object with existing private key in _certPol variable 
// retrieve private key 
var key = _certPol.PrivateKey as RSACryptoServiceProvider; 
// check if it is legacy RSA, otherwise return. 
if (key == null) { return; } 
byte[] dataToSign = Encoding.UTF8.GetBytes(plainText); 
// sign data 
byte[] signature = key.SignData(dataToSign, "SHA256"); 
// Verify signature 
if (!key.VerifyData(dataToSign, "SHA256", signature)) 
    throw new Exception("Nepodařilo se vytvořit platný podpisový kód poplatníka."); 
... 
+0

System.Security.Cryptography.CryptographicExceptionが表示される 追加情報:無効なアルゴリズムが指定されています。上のbyte [] signature = key.SignData(dataToSign、 "SHA256"); –

+0

キーの保存に使用されるCSPはSHA2アルゴリズムをサポートしていないようです。 – Crypt32

+0

でも、どうしたらいいですか?それは同じ証明書です。 –

0

の作業状態は次のとおりです。その代わり、あなたはX509Certificate2オブジェクトのPrivateKeyプロパティに直接RSACryptoServiceProviderを使用する必要があります

var store = new X509Store(StoreName.My, StoreLocation.CurrentUser); 
try 
{ 
    store.Open(OpenFlags.ReadOnly); 
    foreach (var certificate in store.Certificates) 
    { 
     if (certificate.FriendlyName.Equals(certificateName) && certificate.NotAfter.Equals(notAfter)) 
     { 
      _certPopl = certificate; 
      break; 
     } 
    } 
} 
finally 
{ 
    store.Close(); 
} 

ログインし、データを検証:

byte[] dataToSign = Encoding.UTF8.GetBytes(plainText); 
var privKey = (RSACryptoServiceProvider)_certPopl.PrivateKey; 
// Force use of the Enhanced RSA and AES Cryptographic Provider with openssl-generated SHA256 keys 
var enhCsp = new RSACryptoServiceProvider().CspKeyContainerInfo; 
var cspparams = new CspParameters(enhCsp.ProviderType, enhCsp.ProviderName, privKey.CspKeyContainerInfo.KeyContainerName); 
privKey = new RSACryptoServiceProvider(cspparams); 
byte[] signature = privKey.SignData(dataToSign, "SHA256"); 
// Verify signature 
if (!privKey.VerifyData(dataToSign, "SHA256", signature)) 
    throw new Exception("Nepodařilo se vytvořit platný podpisový kód poplatníka."); 
0

.NET 4.6これははるかに簡単です、秘密鍵にアクセスするための新しい方法は、SHA-2署名をはるかに確実に動作します:

using (RSA rsa = cert.GetRSAPrivateKey()) 
{ 
    if (rsa == null) 
    { 
     throw new Exception("Wasn't an RSA key, or no private key was present"); 
    } 

    bool isValid = rsa.VerifyData(
     Encoding.UTF8.GetBytes(plainText), 
     signature, 
     HashAlgorithmName.SHA256, 
     RSASignaturePadding.Pkcs1); 

    if (!isValid) 
    { 
     throw new Exception("VerifyData failed"); 
    } 
} 
関連する問題