Search code examples
c#windows-runtimeencryptionencryption-asymmetric

Encrypt String in winrt c# and decrypt it in c# .net


How one would encrypt a string using asymmetric encryption on WinRT Metro in C# and decrypt this in classic Windows, let's say in a webservice?

I want to use RsaPkcs1 algorithm and I can see that CryptographicKey class and RSAParameters class are not even near compatible.

How this could be accomplished?


Solution

  • I have found the solution on how to export the keys from the CryptographicKey in a format that .net 4 can successfully use.

    CryptographicKey has 2 functions 1. Export and 2. ExportPublicKey. I used the 1st function that exports the private key. This function has 2 parameters 1st is the type of export and 2nd the byte[] that will fill.

    If CryptographicPrivateKeyBlobType.Capi1PrivateKey is used, the blob that Export will produce is compatible with the WinCAPI that RSACryptoServiceProvider of .net 4 can import.

    WinRT

    String str = "String To Encrypt";
    IBuffer buf = CryptographicBuffer.ConvertStringToBinary(str,BinaryStringEncoding.Utf16BE);
    String AsymmetricAlgName = Windows.Security.Cryptography.Core.AsymmetricAlgorithmNames.RsaPkcs1;
    AsymmetricKeyAlgorithmProvider asym = AsymmetricKeyAlgorithmProvider.OpenAlgorithm(AsymmetricAlgName);
    CryptographicKey key = asym.CreateKeyPair(512);
    IBuffer enc = CryptographicEngine.Encrypt(key, buf, null);
    byte[] encryptedbyteArr;
    CryptographicBuffer.CopyToByteArray(enc, out encryptedbyteArr);
    String encryptedBase64Str = Convert.ToBase64String(encryptedbyteArr);
    
    
    //Export the private Key in WinCapi format
    
    byte[] privatekeyBytes;
    CryptographicBuffer.CopyToByteArray(key.Export(CryptographicPrivateKeyBlobType.Capi1PrivateKey), out privatekeyBytes);
    String privatekeyBase64 = Convert.ToBase64String(privatekeyBytes);
    

    encryptedBase64Str now contains the encrypted string in Base64. And lets say that encryptedBase64Str="BwIAAACkAABSU0EyAAIAAAEAAQCFrMTqMU3T14zSUM5..."

    Web Service

    RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
    String privateKey64 = "BwIAAACkAABSU0EyAAIAAAEAAQCFrMTqMU3T14zSUM5...";
    String EncryptedString = "PbauDOjqMLD2P6WSmEw==";
    byte[] EncryptedDataBlob = Convert.FromBase64String(EncryptedString);
    byte[] privateKeyBlob = Convert.FromBase64String(privateKey64);
    byte[] decryptedBytes;
    rsa.ImportCspBlob(privateKeyBlob);
    decryptedBytes = rsa.Decrypt(EncryptedDataBlob, false);
    String decryptedString =System.Text.Encoding.BigEndianUnicode.GetString(decryptedBytes);
    


    decryptedString now contains the decrypted string that WinRT had.