1

I'm trying to work out a way to encrypt a string using a private key, and decrypt it using a public one. I generated the keys using OpenSSL as described in:

http://www.akadia.com/services/ssh_test_certificate.html

This is what I have currently

public static string Encrypt(string str, string key)
{
    try
    {
        key = key.Replace(Environment.NewLine, "");
        IBuffer keyBuffer = CryptographicBuffer.DecodeFromBase64String(key);

        AsymmetricKeyAlgorithmProvider provider = AsymmetricKeyAlgorithmProvider.OpenAlgorithm(AsymmetricAlgorithmNames.RsaPkcs1);

        CryptographicKey publicKey = provider.ImportPublicKey(keyBuffer, CryptographicPublicKeyBlobType.Pkcs1RsaPublicKey);
        IBuffer dataBuffer = CryptographicBuffer.CreateFromByteArray(Encoding.UTF8.GetBytes(str));
        var encryptedData = CryptographicEngine.Encrypt(publicKey, dataBuffer, null);

        return CryptographicBuffer.EncodeToBase64String(encryptedData);
    }
    catch (Exception e)
    {
        throw;
        return "Error in Encryption:With RSA ";
    }
}

However on the ImportPublicKey method I'm getting an exceptin ASN1 corrupted data

the string key passed to that method has following format:

var privateKey =

@"MIICXwIBAAKBgQDUTqfSknFiQx3aepORHJycWck007cfU4fXluTIyf6U9ipDhyPD .... yDxwZVmexltyK5Bwc26lmb+5EtTEic+kZToYWcCucF8lsok=";

so the contents of the OpenSSL generated key file without this part:

-----BEGIN RSA PRIVATE KEY-----
-----END RSA PRIVATE KEY-----
Artjom B.
  • 61,146
  • 24
  • 125
  • 222
alek kowalczyk
  • 4,896
  • 1
  • 26
  • 55

1 Answers1

1

Ok, so my code was pretty wrong, as I wanted to encrypt with the private key, but used the ImportPublicKey function, the correct way should be;

public static string Encrypt(string str, string key)
{
    try
    {
        key = key.Replace(Environment.NewLine, "");
        IBuffer keyBuffer = CryptographicBuffer.DecodeFromBase64String(key);

        AsymmetricKeyAlgorithmProvider provider = AsymmetricKeyAlgorithmProvider.OpenAlgorithm(AsymmetricAlgorithmNames.RsaPkcs1);

        var keyPar = provider.ImportKeyPair(keyBuffer, CryptographicPrivateKeyBlobType.Pkcs1RsaPrivateKey);
        //CryptographicKey publicKey = provider.ImportPublicKey(keyBuffer, CryptographicPublicKeyBlobType.Pkcs1RsaPublicKey);
        IBuffer dataBuffer = CryptographicBuffer.CreateFromByteArray(Encoding.UTF8.GetBytes(str));
        var encryptedData = CryptographicEngine.Encrypt(keyPar, dataBuffer, null);
        var encryptedStr = CryptographicBuffer.EncodeToBase64String(encryptedData);
        var signature = CryptographicEngine.Sign(keyPar, dataBuffer);
        var signatureStr = CryptographicBuffer.EncodeToBase64String(signature);
        return encryptedStr;
    }
    catch (Exception e)
    {
        throw;
        return "Error in Encryption:With RSA ";
    }
}

and this works to encrypt the string using the RSA private key.

However, when I try to decrypt using the public key, using following similar method;

public static string Decrypt(string str, string key)
{
    try
    {
        key = key.Replace(Environment.NewLine, "");
        IBuffer keyBuffer = CryptographicBuffer.DecodeFromBase64String(key);

        AsymmetricKeyAlgorithmProvider provider = AsymmetricKeyAlgorithmProvider.OpenAlgorithm(AsymmetricAlgorithmNames.RsaSignPkcs1Sha256);

        CryptographicKey publicKey = provider.ImportPublicKey(keyBuffer, CryptographicPublicKeyBlobType.X509SubjectPublicKeyInfo);
        IBuffer dataBuffer = CryptographicBuffer.CreateFromByteArray(Encoding.UTF8.GetBytes(str));
        var encryptedData = CryptographicEngine.Decrypt(publicKey, dataBuffer, null);
        return CryptographicBuffer.EncodeToBase64String(encryptedData);
    }
    catch (Exception e)
    {
        throw;
        return "Error in Decryption:With RSA ";
    }
}

I'm getting an Method or operation not implemented exception, either there is still something wrong, or the private-encrypt/public-decrypt method is not yet there in UWP.

What I ended doing is to get the nuget package Portable.BouncyCastle-Signed and follow the code snippet from this answer:

C# BouncyCastle - RSA Encryption with Public/Private keys

Works like a sharm.

Community
  • 1
  • 1
alek kowalczyk
  • 4,896
  • 1
  • 26
  • 55
  • 1
    Please use the official portable version of BouncyCastle, Portable.BouncyCastle. I am the maintainer of the portable fork. If you run into issues, please open an issue in the repo: github.com/onovotny/bc-csharp – Claire Novotny Dec 03 '17 at 01:03