私は暗号化技術が初めてです。このコードが対称暗号化を行うことがわかりました。
byte[] key = //... secret sequence of bytes
byte[] dataToSend = ...
Cipher c = Cipher.getInstance("AES");
SecretKeySpec k = new SecretKeySpec(key, "AES");
c.init(Cipher.ENCRYPT_MODE, k);
byte[] encryptedData = c.doFinal(dataToSend);
その働き。ここで自分のパスワードを使用できます。それがまさに私が必要としていたことです。しかし、128または256の対称暗号化を行う方法がわかりません。コードに128キーと256キーを使用するにはどうすればよいですか?
AESが128ビットモードと256ビットモードのどちらを使用するかは、キーのサイズによって異なります。キーのサイズは128ビットまたは256ビットでなければなりません。通常、パスワードをキーとして使用することはありません。パスワードが必要な長さになることはほとんどないためです。代わりに、いくつかの鍵導出関数を使用して、パスワードから暗号化鍵を導出します。
非常に単純な例:パスワードのMD5を取得して128ビットのキーを取得します。 256ビットのキーが必要な場合は、SHA-256を使用して、パスワードの256ビットのハッシュを取得できます。キー導出関数は通常、このハッシュを数百回実行し、追加のソルトも使用します。詳細は http://en.wikipedia.org/wiki/Key_derivation_function をご覧ください。
また、128ビットよりも強力な暗号化を実行するには、「Java Cryptography Extension(JCE)Unlimited Strength Jurisdiction Policy Files 6」を http://www.Oracle.com/technetwork/Javaからダウンロードしてインストールする必要があります。 /javase/downloads/index.html 。
次の方法は、AES暗号化で文字列(valueEnc
)を暗号化する方法です。
private static final String ALGORITHM = "AES";
public String encrypt(final String valueEnc, final String secKey) {
String encryptedVal = null;
try {
final Key key = generateKeyFromString(secKey);
final Cipher c = Cipher.getInstance(ALGORITHM);
c.init(Cipher.ENCRYPT_MODE, key);
final byte[] encValue = c.doFinal(valueEnc.getBytes());
encryptedVal = new BASE64Encoder().encode(encValue);
} catch(Exception ex) {
System.out.println("The Exception is=" + ex);
}
return encryptedVal;
}
次のメソッドは、AES暗号化文字列(encryptedVal
)を復号化します。
public String decrypt(final String encryptedValue, final String secretKey) {
String decryptedValue = null;
try {
final Key key = generateKeyFromString(secretKey);
final Cipher c = Cipher.getInstance(ALGORITHM);
c.init(Cipher.DECRYPT_MODE, key);
final byte[] decorVal = new BASE64Decoder().decodeBuffer(encryptedValue);
final byte[] decValue = c.doFinal(decorVal);
decryptedValue = new String(decValue);
} catch(Exception ex) {
System.out.println("The Exception is=" + ex);
}
return decryptedValue;
}
secKey
は128ビットの鍵であり、BASE64Encoder
。 BASE64Decoder
次のメソッドでは、適切な128ビットキーを生成します
private Key generateKeyFromString(final String secKey) throws Exception {
final byte[] keyVal = new BASE64Decoder().decodeBuffer(secKey);
final Key key = new SecretKeySpec(keyVal, ALGORITHM);
return key;
}
次のような単純なKeyGeneratorオブジェクトを使用できます。
KeyGenerator generator = KeyGenerator.getInstance("AES/CTR/PKCS5PADDING");
generator.init(128);
SecretKey key = generator.generateKey();
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, key);
...
Cipher.init(...)
に関するJavaのドキュメントから:
public final void init(int opmode、Key key)
スロー:InvalidKeyException-指定されたキーがこの暗号の初期化に不適切である場合、またはこの暗号が復号のために初期化されており、指定されたキーから判別できないアルゴリズムパラメータが必要な場合、または指定されたキーのキーサイズが最大許容値を超える場合キーサイズ(構成されている管轄ポリシーファイルから決定)。
私にとって、これは、Martijn Courteauxのコメントで述べたように、256ビットのキーを使用する必要があります(つまり、32バイトを含むバイト配列でSecretKeySpecを初期化する)と、暗号はそれを受け入れて使用するか、拒否しますサイズが許容できない場合は例外をスローします。
例外が発生する場合、おそらく無制限の強度の暗号ファイルをインストールしていないことが原因です(デフォルトのJDKインストールでは、この crypto specドキュメント )。無制限強度の暗号化パッケージをダウンロード ここ 。
public class CipherUtils
{
private static byte[] key = {
0x74, 0x68, 0x69, 0x73, 0x49, 0x73, 0x41, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x4b, 0x65, 0x79
};//"thisIsASecretKey";
public static String encrypt(String strToEncrypt)
{
try
{
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
final SecretKeySpec secretKey = new SecretKeySpec(key, "AES");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
final String encryptedString = Base64.encodeBase64String(cipher.doFinal(strToEncrypt.getBytes()));
return encryptedString;
}
catch (Exception e)
{
e.printStackTrace();
}
return null;
}
}