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. ステップ 2 の結果を、暗号化プロセスのステップ 1 と同じエンコーディングを使用して文字列に変換します。
于 2012-11-23T07:08:21.610 に答える
0

DecryptionServiceHelper.GetEncryptedSSN では、暗号化する前に IBM037 形式でテキストをエンコードしています。

したがって、暗号化されたバイトを IBM037 形式であると想定して ASCII に変換しているため、次のコードは正しくありません。暗号化されたバイトが IBM037 形式ではないため、これは誤りです (テキストは暗号化の前にエンコードされています)。

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

考えられる解決策の 1 つは、IBM037 形式を使用して暗号化されたテキストをエンコードすることです。これにより、問題が解決するはずです。

于 2012-11-23T07:00:28.337 に答える