4

現在、バイト配列から変換された文字列を返すメソッドがあります。

public static readonly UnicodeEncoding ByteConverter = new UnicodeEncoding();
public static string Decrypt(string textToDecrypt, string privateKeyXml)
{
    if (string.IsNullOrEmpty(textToDecrypt))
    {
        throw new ArgumentException(
            "Cannot decrypt null or blank string"
        );
    }
    if (string.IsNullOrEmpty(privateKeyXml))
    {
        throw new ArgumentException("Invalid private key XML given");
    }
    byte[] bytesToDecrypt = Convert.FromBase64String(textToDecrypt);
    byte[] decryptedBytes;
    using (var rsa = new RSACryptoServiceProvider())
    {
        rsa.FromXmlString(privateKeyXml);
        decryptedBytes = rsa.Decrypt(bytesToDecrypt, FOAEP);
    }
    return ByteConverter.GetString(decryptedBytes);
}

代わりに を返すようにこのメソッドを更新しようとしていますが、 の戻り値をからにSecureString変換するのに問題があります。私は次のことを試しました:RSACryptoServiceProvider.Decryptbyte[]SecureString

var secStr = new SecureString();
foreach (byte b in decryptedBytes)
{
    char[] chars = ByteConverter.GetChars(new[] { b });
    if (chars.Length != 1)
    {
        throw new Exception(
            "Could not convert a single byte into a single char"
        );
    }
    secStr.AppendChar(chars[0]);
}
return secStr;

ただし、この SecureString equality testerを使用すると、結果は元の暗号化されていないテキストから構築されたものSecureStringと等しくありませんでした。SecureString私の Encrypt メソッドと Decrypt メソッドは、以前はstringどこでも使用していたときに機能し、SecureString等価コードもテストしたので、ここでの問題は に変換しようとしている方法にあると確信していbyte[]ますSecureString。RSA 暗号化を使用するために取るべき別のルートはありSecureStringますか?

編集:SecureStringバイト配列を通常の文字列に変換してから、その文字列を aに詰め込みたくありませんでしSecureString. Decryptただし、返されるのも悪いので、byte[]そのバイト配列をに詰め込もうとしていSecureStringますか? 私の推測では、 ifDecryptが a を返す場合byte[]、それは機密情報を安全に渡す方法なので、データの 1 つの安全な表現を別の安全な表現に変換しても問題ないようです。

4

5 に答える 5

3

char と byte はキャストと同じ意味で使用できるため、コードの 2 番目のチャンクを次のように変更します。

var secStr = new SecureString();
foreach (byte b in decryptedBytes)
{
   secStr.AppendChar((char)b);
}

return secStr;

これは適切に機能するはずですが、暗号化されていない情報をメモリ内の「クリア」にまだ持っていることに注意してくださいSecureString

**更新**

byte[]あなたの機密情報の Aは安全ではありません。メモリ内でそれを見て、情報を確認できます (特に文字列だけの場合)。個々のバイトは文字列の正確な順序になるため、「読み取る」のは非常に簡単です。

私は(実際には約1時間前に)この同じ問題に自分自身で苦労していました。私の知るSecureString限り、デクリタがこの戦略をサポートするように特別にプログラムされていない限り、デクリプタから直接行く良い方法はありません.

于 2010-12-21T20:31:35.457 に答える
0

Coding Gorilla's answerに基づいて、私は自分の方法で次のことを試しましたDecrypt:

string decryptedString1 = string.Empty;
foreach (byte b in decryptedBytes)
{
    decryptedString1 += (char)b;
}
string decryptedString2 = ByteConverter.GetString(decryptedBytes);

デバッグ時、decryptedString1decryptedString2は等しくありませんでした:

decryptedString1    "m\0y\0V\0e\0r\0y\0L\0o\0n\0g\0V\03\0r\0y\05\03\0c\0r\03\07\0p\04\0s\0s\0w\00\0r\0d\0!\0!\0!\0"
decryptedString2    "myVeryLongV3ry53cr37p4ssw0rd!!!"

したがって、byte[]配列を調べて、に直接キャストし、文字charをスキップできるようです。\0ただし、Coding Gorilla が言ったようにSecureString、機密データは小さなbyteサイズのチャンクでメモリ内を浮遊しているため、これもまた . 直接RSACryptoServiceProvider.Decrypt返すための提案はありますか?SecureString

編集:はい、これは機能します:

var secStr = new SecureString();
foreach (byte b in decryptedBytes)
{
    var c = (char)b;
    if ('\0' == c)
    {
        continue;
    }
    secStr.AppendChar(c);
}
return secStr;

編集:訂正: これは古い英語の文字列で動作します。文字列を暗号化してから復号化しよう"標準語 明治維新 english やった"としても、このforeach (byte b in decryptedBytes)手法を使用して復号化された文字列が元の暗号化されていない文字列と一致しないため、期待どおりに機能しません。

編集:両方で次の作品を使用:

var secStr = new SecureString();
foreach (char c in ByteConverter.GetChars(decryptedBytes))
{
    secStr.AppendChar(c);
}
return secStr;

これでも、パスワードの byte 配列と char 配列がメモリに残ります。たぶん、.a を返す別の RSA クラスを見つける必要がありますSecureString。:/

于 2010-12-21T20:42:09.890 に答える
-1

System.Encoding.Default.GetString を使用 GetString MSDN

于 2010-12-21T20:26:18.130 に答える