0

我有一个加密方法 GetDecryptedSSN()。我通过以下测试测试了它的正确性。它工作正常

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

但是当我转换为 ASCII 字符串然后返回时,它无法正常工作。转换逻辑有什么问题?

        //////////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);

助手类

 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);
    }

}

参考

  1. 使用 AesCryptoServiceProvider 获取不正确的解密值
4

2 回答 2

1

这就是问题所在,我怀疑:

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

(由于事先所有的编码都搞乱了,这并不完全清楚,这对我来说似乎毫无意义,但是......)

加密的结果不是“用 ASCII 编码的文本”——所以你不应该试图那样对待它。(您还没有说您使用的是哪种加密,但它会产生 ASCII 文本会奇怪。)

它只是一个任意字节数组。为了在文本中仅使用 ASCII 字符集来表示,最常见的方法是使用 base64。所以上面的代码会变成:

string encryptedText = Convert.ToBase64(encryptedByteWithIBMEncoding);

然后,您将其转换回一个字节数组,准备好解密,如下所示:

encryptedByteWithIBMEncoding = Convert.FromBase64String(encryptedText);

如果您能提供帮助,我强烈建议您避免使用这样的编码。目前还不清楚为什么 ASCII 需要参与进来如果您真的想在加密之前将原始文本编码为 IBM037,您应该只使用:

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

就我个人而言,我通常使用 UTF-8 作为一种编码,它可以处理任何字符数据,而不仅仅是一个有限的子集,但这取决于你。我认为你让整个事情变得比它需要的复杂得多。

一个典型的“加密一个字符串,得到一个字符串结果”的工作流程是:

  1. 使用 UTF-8 将输入文本转换为字节。结果是一个字节数组。
  2. 加密步骤 1 的结果。结果是一个字节数组。
  3. 将步骤 2 的结果转换为 base64。结果是一个字符串。

解密:

  1. base64转换字符串。结果是一个字节数组。
  2. 解密步骤1的结果。结果是一个字节数组。
  3. 使用与加密过程的步骤 1 相同的编码将步骤 2 的结果转换回字符串。
于 2012-11-23T07:08:21.610 回答
0

在 DecryptionServiceHelper.GetEncryptedSSN 中,您在加密之前以 IBM037 格式对文本进行编码。

因此,以下代码不正确,因为您将加密字节转换为 ASCII,假设它采用 IBM037 格式。这是错误的,因为加密的字节不是 IBM037 格式(文本是在加密之前编码的)

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

一种可能的解决方案是使用 IBM037 格式对加密文本进行编码,这应该可以解决我猜的问题。

于 2012-11-23T07:00:28.337 回答