2

BigInteger最大19桁の長さを取り、次のルールで暗号化するにはどうすればよいですか。

  • 結果は、数字と小文字の英字のみに基づいている必要があります。
  • すべての出力は、どの入力に対しても同じ長さである必要があります。長さは、メソッドに応じて11〜16文字である必要がありますが、すべての可能な入力に対して一貫している必要があります
  • 簡単なパターンはありません。たとえば、000...1と000...2を暗号化すると、結果は完全に異なって見えるはずです。
  • 衝突はまったくありません
  • 元のBigIntegerに復号化できるはずです。

私が試したこと

  • 元の数値を取得し、それを何らかのキーでXORし、係数を掛けて、36進数の文字列に変換します。この係数の目的は、範囲を拡大して、0のパディングが多すぎないようにすることです。係数は1からまででなければなりません36^16/10^19。この方法の問題は、a)十分に「安全」ではなく、b)近い数の結果が非常に似ていることです。

  • この答え。ただし、結果が短すぎたり長すぎたりすることが多く、以前に使用された因数分解法はここでは機能しませんでした。

4

3 に答える 3

3

19桁は64ビットよりわずかに少ないため、ECBモードのTDEAのような8バイトのブロック暗号を使用してBigInteger値を暗号化できます。最初にBigIntegerのデフォルトの64ビットエンコーディングを取得し、次に秘密鍵で暗号化し、最後にベース36でエンコードします。結果は16文字未満の数文字になりますが、いつでも任意の値で埋めることができます。

同じ値を2回暗号化すると同じ結果が得られることに注意してください。そのため、暗号文はプレーンテキストに関する情報をリークします。

于 2013-03-16T18:03:46.090 に答える
0

BigIntegerをに変換できる場合は、これを実行しているように見えるコードを次に示しますulong(9999999999999999999は実際にはulong)です。結果は常に固定の16文字の文字列(16進数)になります。

    byte[] key = // put your 16-bytes private key here
    byte[] iv = Guid.NewGuid().ToByteArray(); // or anything that varies and you can carry

    string s = EncryptUInt64(ul, key, iv); // encode
    ulong dul = DecryptUInt64(s, key, iv).Value; // decode if possible


    public static string EncryptUInt64(ulong ul, byte[] key, byte[] iv)
    {
        using (MemoryStream output = new MemoryStream())
        using (var algo = TripleDES.Create())
        {
            algo.Padding = PaddingMode.None;
            using (CryptoStream stream = new CryptoStream(output, algo.CreateEncryptor(key, iv), CryptoStreamMode.Write))
            {
                byte[] ulb = BitConverter.GetBytes(ul);
                stream.Write(ulb, 0, ulb.Length);
            }
            return BitConverter.ToUInt64(output.ToArray(), 0).ToString("x16");
        }
    }

    public static ulong? DecryptUInt64(string text, byte[] key, byte[] iv)
    {
        if (text == null)
            return null;

        ulong ul;
        if (!ulong.TryParse(text, NumberStyles.HexNumber, null, out ul))
            return null;

        using (MemoryStream input = new MemoryStream(BitConverter.GetBytes(ul)))
        using (var algo = TripleDES.Create())
        {
            algo.Padding = PaddingMode.None;
            using (CryptoStream stream = new CryptoStream(input, algo.CreateDecryptor(key, iv), CryptoStreamMode.Read))
            {
                byte[] olb = new byte[8];
                try
                {
                    stream.Read(olb, 0, olb.Length);
                }
                catch
                {
                    return null;
                }
                return BitConverter.ToUInt64(olb, 0);
            }
        }
    }
于 2013-03-21T14:46:35.357 に答える
0

必要な手法は、フォーマットを保持する暗号化です。これにより、19桁の数字を別の19桁の数字として暗号化できます。

残念ながら、この手法の効率的なバージョンを実装するのはやや困難であり、実際、間違ったパラメータを選択すると、非常に安全に実行できなくなります。そのためのライブラリがあります。 これはオープンソースです。残念ながらC++であり、Windowsで実行されるかどうかは明確ではありません。 Voltageにもライブラリがありますが、おそらくお金がかかり、どの言語をサポートしているかはわかりません。

于 2013-03-21T05:51:34.763 に答える