12 バイトのデータを暗号化する対称鍵暗号方式を探しています。ご覧のとおり、ブロック暗号化アルゴリズムを使用するには 64 ビットまたは 128 ビットの境界に準拠していません。また、暗号化されたデータの長さに制限があるため、データをパディングしたくありません。制限は、base 32 を使用して 20 文字を超えることができない印刷可能なキーに変換するためです。プレーン テキストには非常に予測可能なデータ パターンが含まれているため、暗号化方式でそれを隠すことができるはずです。私が理解していることから、疑似ランダムキーの生成がこの問題の唯一の解決策ですが、データを暗号化するソリューションとそれを復号化するソリューションは互いに対話しません。
3 に答える
なぜ RC4 を使わないのですか? 暗号文は平文とまったく同じサイズです - この場合は 12 バイトです。Java (5 以上) が付属しています。次に例を示します。
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
public class MyArcFour
{
public static void main(String [] args) throws Exception
{
byte [] key = "MYVERYINSECUREKEY".getBytes("ASCII");
String clearText = "123456789012";
Cipher rc4 = Cipher.getInstance("RC4");
SecretKeySpec rc4Key = new SecretKeySpec(key, "RC4");
rc4.init(Cipher.ENCRYPT_MODE, rc4Key);
byte [] cipherText = rc4.update(clearText.getBytes("ASCII"));
System.out.println("clear (ascii) " + clearText);
System.out.println("clear (hex) " + DatatypeConverter.printHexBinary(clearText.getBytes("ASCII")));
System.out.println("cipher (hex) is " + DatatypeConverter.printHexBinary(cipherText));
Cipher rc4Decrypt = Cipher.getInstance("RC4");
rc4Decrypt.init(Cipher.DECRYPT_MODE, rc4Key);
byte [] clearText2 = rc4Decrypt.update(cipherText);
System.out.println("decrypted (clear) is " + new String(clearText2, "ASCII"));
}
}
これにより、次の出力が生成されます。
clear (ascii) 123456789012
clear (hex) 313233343536373839303132
cipher (hex) is CBFB9A712E55EBD985C8F2DF
decrypted (clear) is 123456789012
もちろん、例よりも優れた (より長く、よりランダムな) キーを使用することをお勧めします。
RC4 のようなストリーム暗号を使用できますが、おわかりのように、キーを再利用することはできません。ストリーム暗号の場合、キー/ノンス (ノンス = 1 回使用される数値) の組み合わせを使用します。ノンスは、1、2、3、4、...、または日付/時刻のように単純にすることができ、暗号文と一緒に保存する必要があります。nonce がゼロに丸められて繰り返しが開始される前にキーを変更します。日付/時刻を使用する場合は、値が繰り返されないように時計が十分速く刻むようにしてください。
長期キーとナンスがあります。何かを暗号化するたびに、それらをハッシュしてセッション キーを取得します。
sessionKey <- SHA256(longTermKey + nonce)
このセッション キーは 1 回だけ使用し、その後は破棄してください。復号化に使用するナンスを保存します。次の使用に備えて数値ノンスをインクリメントします。日付/時刻ナンスの場合、クロックが変更されたことを確認するために短い遅延を挿入します。次回使用するときは、ナンスが異なっている必要があります。
長期キーを変更すると、すべてのデータを復号化して再暗号化する必要があります。または、ナンスに大きなビットサイズを選択し、長期的な鍵を非常に安全に保ちます。
ストリーム暗号が必要/必要: http://en.wikipedia.org/wiki/Stream_cipher