4

Win 8 Metro アプリと RESTful WCF サービスの間で暗号化されたデータを渡そうとしています。最初に、Metro アプリは公開キーを要求し、WCF サービスは厄介な書式設定の問題を回避するために、生のストリームとしてそれを返します。Base 64 でエンコードされた公開キーは、metro アプリでバイト配列にデコードされます。ここで問題が発生します。AsymmetricKeyAlgorithmProvider.ImportPublicKey を呼び出そうとすると、「ASN1 bad tag value met」というエラーが表示されます。

暗号化には RSA PKCS1 を使用しています。関連するコードは次のとおりです。

WCF サービス

     string keyName = "This is passed in via a parameter";
     var key = !CngKey.Exists(keyName) ? CngKey.Create(CngAlgorithm2.Rsa, keyName) : CngKey.Open(keyName);

     // Create the RSA container to get keys and then dispose
     using (var rsaCng = new RSACng(key) { EncryptionPaddingMode = AsymmetricPaddingMode.Pkcs1, KeySize = 2048 })
     {
        byte[] publicBlob = rsaCng.Key.Export(CngKeyBlobFormat.GenericPublicBlob);
        publicKey = Convert.ToBase64String(publicBlob);
     }

メトロアプリ

  public static string Encrypt(IBuffer dataBuffer, string publicKeyString)
  {
     var asymmAlg = AsymmetricKeyAlgorithmProvider.OpenAlgorithm(AsymmetricAlgorithmNames.RsaPkcs1);
     // The next line fails with ASN1 bad tag value met
     var publicKey = asymmAlg.ImportPublicKey(CryptographicBuffer.DecodeFromBase64String(publicKeyString), CryptographicPublicKeyBlobType.Pkcs1RsaPublicKey);

     var encryptedData = CryptographicEngine.Encrypt(publicKey, dataBuffer, null);
     return CryptographicBuffer.EncodeToBase64String(encryptedData);
  }

編集1:以下の詳細情報

WCF サービスから 2048 ビットのキー ペアから公開キーをエクスポートすると、283 ビット長のキー BLOB が生成されますが、Metro アプリから同じ種類の公開キーをエクスポートすると、わずか 270 ビットになります。Metro で生成された公開鍵をインポートすると、成功します。WCF サービスの公開鍵に 13 ビットの余分なビットがあるのはなぜですか? これらの余分な 13 ビットが失敗の原因だと思います。

以下は、短い公開鍵 blob を生成する Metro コードです。

var provider = AsymmetricKeyAlgorithmProvider.OpenAlgorithm(AsymmetricAlgorithmNames.RsaPkcs1);
CryptographicKey standardKeyPair = provider.CreateKeyPair(2048);
byte[] standardKey = standardKeyPair.ExportPublicKey(CryptographicPublicKeyBlobType.Pkcs1RsaPublicKey).ToArray();
4

1 に答える 1

1

かなり遅いですが、多分それはあなたを助けたり、誰かの時間を節約したりします...

インポート中に BLOB タイプのタイプを変更します。それは本当に奇妙ですが、実験の結果、成功しました。

WCF のコードはそのままである場合があります。

Metro コードのみを変更します。

public static string Encrypt(IBuffer dataBuffer, string publicKeyString)
{
    var asymmAlg = AsymmetricKeyAlgorithmProvider.OpenAlgorithm(AsymmetricAlgorithmNames.RsaPkcs1);
    // The next line fails with ASN1 bad tag value met
    var publicKey = asymmAlg.ImportPublicKey(CryptographicBuffer.DecodeFromBase64String(publicKeyString), CryptographicPublicKeyBlobType.BCryptPublicKey);

    var encryptedData = CryptographicEngine.Encrypt(publicKey, dataBuffer, null);
    return CryptographicBuffer.EncodeToBase64String(encryptedData);
}

したがって、ここでの唯一の変更はBCryptPublicKey、インポート中です。その後、動作します。しかし、理由を聞かないでください:-)。

于 2013-05-20T14:23:34.097 に答える