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 回答