2

So, what I need is next:

  1. Create certifiactes for development, get one for the client and one for server
  2. Retrieve password through API that is encoded from client and decode it on server

Now, I managed to create certifiactes following this link. The girl there gave step by step instructions on how to get self signed certifiactes, put them in store, etc... Now, the part I'm having problem with:

I've managed to encrypt my data using this code:

public static string Encrypt(string stringForEncription, string PathToPrivateKey)
    {
        X509Certificate2 myCertificate;
        try
        {
            myCertificate = new X509Certificate2(PathToPrivateKey, "Test123");
        }
        catch (Exception e)
        {
            throw new CryptographicException("Unable to open key file.");
        }

        RSACryptoServiceProvider rsaObj;
        if (myCertificate.HasPrivateKey)
        {
            rsaObj = (RSACryptoServiceProvider)myCertificate.PrivateKey;
        }
        else
            throw new CryptographicException("Private key not contained within certificate.");

        if (rsaObj == null)
            return String.Empty;

        byte[] decryptedBytes;
        byte[] array = Encoding.UTF8.GetBytes(stringForEncription);
        try
        {
            decryptedBytes = rsaObj.Encrypt(array, false);
            //decryptedBytes = rsaObj.Encrypt(Convert.FromBase64String(Base64EncryptedData), false);
        }
        catch (Exception e)
        {
            throw new CryptographicException("Unable to encrypt data.");
        }

        //    Check to make sure we decrpyted the string 
        if (decryptedBytes.Length == 0)
            return String.Empty;
        else
            return System.Text.Encoding.UTF8.GetString(decryptedBytes);
    }

For PathToPrivate key variable I am using the path to my client ClientCert.pfx. I don't know if I should use any other, but here is the snap of the folder with all the certificates that I made:

enter image description here

Now, for the decryption, I'm using next code:

 public static string DecryptEncryptedData(string Base64EncryptedData, string PathToPrivateKey)
    {
        X509Certificate2 myCertificate;
        try
        {
            myCertificate = new X509Certificate2(PathToPrivateKey, "Test123");
        }
        catch (Exception e)
        {
            throw new CryptographicException("Unable to open key file.");
        }

        RSACryptoServiceProvider rsaObj;
        if (myCertificate.HasPrivateKey)
        {
            rsaObj = (RSACryptoServiceProvider)myCertificate.PrivateKey;
        }
        else
            throw new CryptographicException("Private key not contained within certificate.");

        if (rsaObj == null)
            return String.Empty;

        byte[] decryptedBytes;
        try
        {
            decryptedBytes = rsaObj.Decrypt(Convert.FromBase64String(Base64EncryptedData), false);
        }
        catch (Exception e)
        {
            throw new CryptographicException("Unable to decrypt data.");
        }

        //    Check to make sure we decrpyted the string 
        if (decryptedBytes.Length == 0)
            return String.Empty;
        else
            return System.Text.Encoding.UTF8.GetString(decryptedBytes);
    }

And whatever I try to do, it gives me exception:

{"The input is not a valid Base-64 string as it contains a non-base 64 character, more than two padding characters, or an illegal character among the padding characters. "}

Would really apreciate somebody helping me out.

Kay Lee
  • 922
  • 1
  • 12
  • 40
Miljan Vulovic
  • 1,586
  • 3
  • 20
  • 48
  • @KayLee Tried that, not working, certificates are alright, keys are there, I think the problem is in converting to Base64String and from Base64String – Miljan Vulovic Feb 14 '17 at 14:01
  • Try to test DecryptEncryptedData("hello", string PathToPrivateKey); Maybe, same exception message would show as per my experience. This means the argument is not properly formatted(not properly encrypted). Hope this provides some clue. I'm sure this is all about the format as byte, base64string, decryptedplainstring. Analyze some example blog like MSDN carefully and it's not difficult. – Kay Lee Feb 14 '17 at 14:03
  • I'll come back tomorrow morning after reviewing my code. Here is late night. – Kay Lee Feb 14 '17 at 14:18
  • @KayLee alright, thank you! – Miljan Vulovic Feb 14 '17 at 14:34
  • Can you update your question with the returned string by Encrypt method? I mean the string which you also try to decrypt. And what do you mean by encoded from client? If you don't limit users, black users might create their login, password and connect to Sever. – Kay Lee Feb 14 '17 at 15:24
  • The \r\n in 'The incorrect parameter is \r\n' means just kind of one blank line and \n means just next line (without one blank line) in string format which Computer understands. All this means the target to be decrypted is wrong.. – Kay Lee Feb 15 '17 at 01:11

2 Answers2

0

The reason you are getting the error is the string you are trying to Convert.FromBase64String from a value that is not actually a base-64 string.

After encrypting your data, you should convert the byte array to a base-64 string. Use Convert.ToBase64String for this.

return Convert.ToBase64String(decryptedBytes);

Then your decrypt line will work:

decryptedBytes = rsaObj.Decrypt(Convert.FromBase64String(Base64EncryptedData), false);

Zesty
  • 2,922
  • 9
  • 38
  • 69
  • Convert.ToBase64String(stringForEncription); returns string, not byte[], any suggestions? – Miljan Vulovic Feb 14 '17 at 13:03
  • Ok, got what you meant, I returned Convert.ToBase64String(decryptedBytes); and after that, in decrtypt method, I get: {"The parameter is incorrect.\r\n"} – Miljan Vulovic Feb 14 '17 at 13:08
  • try { decryptedBytes = rsaObj.Decrypt(Convert.FromBase64String(Base64EncryptedData), false); } catch (Exception e) { throw new CryptographicException("Unable to decrypt data."); } – Miljan Vulovic Feb 14 '17 at 13:14
0

This is not the exact answer which you might expected but I write here as it's too long as a comment.

I think the decryption itself has no problem at all (I've found the example blog of your code with php encryption) That's why I commented I was curious on the encryptedstring which is the target of decryption.

I also struggled in understanding Security for months and now I use symmetric(AES) and asymmetric(RSA) together. Understanding is really important and everybody takes time..

RSA is asymmetric and one-way which means the Encryption can be done only by public key and the Decryption can be done only by private key. You're using private key in Encryption method and it seems just copied from Decryption.

The answer by Zesty is right only in terms of formatting. You're also needed to understand the formatting. We need Convert.ToBase64String and Convert.FromBase64String in Encryption and Decryption from byte to base64string and vice versa. However this base64string is not just plain like 'hello' but 'SABlAGwAbABvACAAVwBvAHIAbABkAA==' as you see here

And I kindly recommend to use complete solution(not half one like php encryption) like this blog so that Encryption and Decryption and all are in harmony.

And as last as I commented also, you're needed to think about how to prevent the black users if encryption is done from client side and you don't have only good users.

I hope my experience helps to understand Security which is of most importance.

Community
  • 1
  • 1
Kay Lee
  • 922
  • 1
  • 12
  • 40