问题
I have public key modulus and public key exponent and I need to generate a public key and encrypt data in metro style application. in c# we have RSAParameters class but I cannot find any thing of such sort for metro style applications.
when I use the base64encoded public key directly received from the certificate and try to import the key with the below code I get an exception thrown ASN1 bad tag value met. which i think is due to the invalid format of the data.
//sample dummy key from certificate in base64encoded
string key = @"MIIB0zCCAX2gAwIBAgIJAMF/bHcA799IMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwHhcNMTIwMzI3MTEyNjQ5WhcNMTMwMzI3MTEyNjQ5WjBFMQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAMEPeWjP4sdqxvBlDId4BtRRTeWPwjlZLSOFvOVgmoSyoPva8psFUF6tH9/vPXIJrL80tdCoBt8YFH6pwDN9a1sCAwEAAaNQME4wHQYDVR0OBBYEFGARqQfUhX7atVU4sS+aQAPt/jFxMB8GA1UdIwQYMBaAFGARqQfUhX7atVU4sS+aQAPt/jFxMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADQQALqOyjovRbWUZvziVaE8QYy83WEln1l+HJU9D6tFncUZTlwSd8aUwyQsd3zOVNZ41oCAVv5R3h1jtBtPbM+c1K";
symmetricKeyAlgorithmProvider asymmAlg = AsymmetricKeyAlgorithmProvider.OpenAlgorithm("RSA_OAEP_SHA1");
CryptographicKey publicKey = asymmAlg.ImportPublicKey(CryptographicBuffer.DecodeFromBase64String(key));
string input64string ="encrypt this";
IBuffer dataToEncrypt = CryptographicBuffer.DecodeFromBase64String(input64string);
IBuffer encryptedData = CryptographicEngine.Encrypt(publicKey, dataToEncrypt, null);
回答1:
Your key
is the modulus part of the public key, whose length is 128. Consider the standard key exported from C# code in metro:
using System.Runtime.InteropServices.WindowsRuntime;
CryptographicKey standardKeyPair = provider.CreateKeyPair(1024);
byte[] standardKey = standardKeyPair.ExportPublicKey(CryptographicPublicKeyBlobType.Pkcs1RsaPublicKey).ToArray();
you can see the length of the byte[] standardKey is 140,which has 7 bits prefix and 5 bits tail. I don't know the reason, but I copied the extra 12 bits to the known key, it works. Hope this helps you:
public static IBuffer RsaEncrypt(this IBuffer dataToEncrypt, string publicKeyN)
{
AsymmetricKeyAlgorithmProvider provider = AsymmetricKeyAlgorithmProvider.OpenAlgorithm(AsymmetricAlgorithmNames.RsaPkcs1);
CryptographicKey standardKeyPair = provider.CreateKeyPair(1024);
byte[] standardKey = standardKeyPair.ExportPublicKey(CryptographicPublicKeyBlobType.Pkcs1RsaPublicKey).ToArray();
var data_n = CryptographicBuffer.DecodeFromBase64String(publicKeyN).ToArray();
Array.Copy(data_n, 0, standardKey, 7, data_n.Length);
var key = provider.ImportPublicKey(standardKey.AsBuffer(), CryptographicPublicKeyBlobType.Pkcs1RsaPublicKey);
var result = CryptographicEngine.Encrypt(key, dataToEncrypt, null);
return result;
}
回答2:
This should do what you are asking:
public static IBuffer RsaEncrypt(byte[] modulus, byte[] exponent, IBuffer data)
{
var rsa = AsymmetricKeyAlgorithmProvider.OpenAlgorithm(AsymmetricAlgorithmNames.RsaOaepSha1);
var keyBlob = modulus.Concat(exponent).ToArray().AsBuffer();
var publicKey = rsa.ImportPublicKey(keyBlob, CryptographicPublicKeyBlobType.Pkcs1RsaPublicKey);
return CryptographicEngine.Encrypt(publicKey, data, null);
}
Of course, you can still use base64 strings as input/output if want, but you already know how to do that. :)
If you dig down to page 61 of RFC3447 you will find that the public key format structure is just the modulus followed by the exponent, which is why I concatenated them.
来源:https://stackoverflow.com/questions/11880450/rsa-encryption-in-metro-style-application