0

I have a encryption method GetDecryptedSSN(). I tested it’s correctness by the following test. It works fine

        //////////TEST 2//////////
        byte[] encryptedByteWithIBMEncoding2 = DecryptionServiceHelper.GetEncryptedSSN("123456789");
        string clearTextSSN2 = DecryptionServiceHelper.GetDecryptedSSN(encryptedByteWithIBMEncoding2);

But when I do a conversion to ASCII String and then back, it is not working correctly. What is the problem in the conversion logic?

        //////////TEST 1////////// 
        //String  -- > ASCII Byte --> IBM Byte -- > encryptedByteWithIBMEncoding
        byte[] encryptedByteWithIBMEncoding = DecryptionServiceHelper.GetEncryptedSSN("123456789");

        //encryptedByteWithIBMEncoding -->  Encrypted Byte ASCII
        string EncodingFormat = "IBM037";
        byte[] encryptedByteWithASCIIEncoding = Encoding.Convert(Encoding.GetEncoding(EncodingFormat), Encoding.ASCII,
                encryptedByteWithIBMEncoding);


        //Encrypted Byte ASCII - ASCII Encoded string 
        string encodedEncryptedStringInASCII = System.Text.ASCIIEncoding.ASCII.GetString(encryptedByteWithASCIIEncoding);
        //UpdateSSN(encodedEncryptedStringInASCII);

        byte[] dataInBytesASCII = System.Text.ASCIIEncoding.ASCII.GetBytes(encodedEncryptedStringInASCII);
        byte[] bytesInIBM = Encoding.Convert(Encoding.ASCII, Encoding.GetEncoding(EncodingFormat),
                dataInBytesASCII);
        string clearTextSSN = DecryptionServiceHelper.GetDecryptedSSN(bytesInIBM);

Helper Class

 public static class DecryptionServiceHelper
{
    public const string EncodingFormat = "IBM037";
    public const string SSNPrefix = "0000000";
    public const string Encryption = "E";
    public const string Decryption = "D";

    public static byte[] GetEncryptedSSN(string clearTextSSN)
    {
        return GetEncryptedID(SSNPrefix + clearTextSSN);
    }

    public static string GetDecryptedSSN(byte[] encryptedSSN)
    {
        return GetDecryptedID(encryptedSSN);
    }

    private static byte[] GetEncryptedID(string id)
    {
        ServiceProgram input = new ServiceProgram();
        input.RequestText = Encodeto64(id);
        input.RequestType = Encryption;

        ProgramInterface inputRequest = new ProgramInterface();
        inputRequest.Test__Request = input;

        using (MY_Service operation = new MY_Service())
        {
            return ((operation.MY_Operation(inputRequest)).Test__Response.ResponseText);
        }
    }


    private static string GetDecryptedID(byte[] id)
    {
        ServiceProgram input = new ServiceProgram();
        input.RequestText = id;
        input.RequestType = Decryption;

        ProgramInterface request = new ProgramInterface();
        request.Test__Request = input;

        using (MY_Service operationD = new MY_Service())
        {
            ProgramInterface1 response = operationD.MY_Operation(request);
            byte[] encodedBytes = Encoding.Convert(Encoding.GetEncoding(EncodingFormat), Encoding.ASCII,
                response.Test__Response.ResponseText);

            return System.Text.ASCIIEncoding.ASCII.GetString(encodedBytes);
        }
    }

    private static byte[] Encodeto64(string toEncode)
    {
        byte[] dataInBytes = System.Text.ASCIIEncoding.ASCII.GetBytes(toEncode);
        Encoding encoding = Encoding.GetEncoding(EncodingFormat);
        return Encoding.Convert(Encoding.ASCII, encoding, dataInBytes);
    }

}

REFERENCE:

  1. Getting incorrect decryption value using AesCryptoServiceProvider
Community
  • 1
  • 1
LCJ
  • 22,196
  • 67
  • 260
  • 418

2 Answers2

1

This is the problem, I suspect:

string encodedEncryptedStringInASCII = 
    System.Text.ASCIIEncoding.ASCII.GetString(encryptedByteWithASCIIEncoding);

(It's not entirely clear because of all the messing around with encodings beforehand, which seems pointless to me, but...)

The result of encryption is not "text encoded in ASCII" - so you shouldn't try to treat it that way. (You haven't said what kind of encryption you're using, but it would be very odd for it to produce ASCII text.)

It's just an arbitrary byte array. In order to represent that in text only using the ASCII character set, the most common approach is to use base64. So the above code would become:

string encryptedText = Convert.ToBase64(encryptedByteWithIBMEncoding);

Then later, you'd convert it back to a byte array ready for decryption as:

encryptedByteWithIBMEncoding = Convert.FromBase64String(encryptedText);

I would strongly advise you to avoid messing around with the encodings like this if you can help it though. It's not clear why ASCII needs to get involved at all. If you really want to encode your original text as IBM037 before encryption, you should just use:

Encoding encoding = Encoding.GetEncoding("IBM037");
string unencryptedBinary = encoding.GetBytes(textInput);

Personally I'd usually use UTF-8, as an encoding which can handle any character data rather than just a limited subset, but that's up to you. I think you're making the whole thing much more complicated than it needs to be though.

A typical "encrypt a string, getting a string result" workflow is:

  1. Convert input text to bytes using UTF-8. The result is a byte array.
  2. Encrypt result of step 1. The result is a byte array.
  3. Convert result of step 2 into base64. The result is a string.

To decrypt:

  1. Convert the string from base64. The result is a byte array.
  2. Decrypt the result of step 1. The result is a byte array.
  3. Convert the result of step 2 back to a string using the same encoding as step 1 of the encryption process.
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
0

In DecryptionServiceHelper.GetEncryptedSSN you are encoding the text in IBM037 format BEFORE encrypting.

So the following piece of code is not correct as you are converting the encrypted bytes to ASCII assuming that its in the IBM037 format. That's wrong as the encrypted bytes is not in IBM037 format (the text was encoded before encryption)

//encryptedByteWithIBMEncoding -->  Encrypted Byte ASCII
string EncodingFormat = "IBM037";
byte[] encryptedByteWithASCIIEncoding = Encoding.Convert(Encoding.GetEncoding(EncodingFormat), Encoding.ASCII,
        encryptedByteWithIBMEncoding);

One possible solution is to encode the encrypted text using IBM037 format, that should fix the issue I guess.

Raam
  • 10,296
  • 3
  • 26
  • 27