0

以下のコードは PBE アルゴリズムをSALT使用しています。提供されたパスワードに数バイトを追加するために配列が使用されていることを理解しています。しかし、その配列からいくつかの要素を削除しようとすると、プログラムを実行するとエラーが発生します。

私の質問は、SALT以下のプログラムで使用される配列を変更できるかどうかです。はいの場合、変更したときにエラーが発生するのはなぜですか?

このコードを確認して、理解を深めてください。SALTこの配列とは別に、プログラムに関する簡単な説明をいただければ幸いです。

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.GeneralSecurityException;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

public class ProtectedConfigFile {

private static final char[] PASSWORD = "enfldsgbnlsngdlksdsgm".toCharArray();
private static final byte[] SALT = {
    (byte) 0xde, (byte) 0x33, (byte) 0x10, (byte) 0x12,
    (byte) 0xde, (byte) 0x33, (byte) 0x10, (byte) 0x12,
};

public static void main(String[] args) throws Exception {
    String originalPassword = "secret";
    System.out.println("Original password: " + originalPassword);
    String encryptedPassword = encrypt(originalPassword);
    System.out.println("Encrypted password: " + encryptedPassword);
    String decryptedPassword = decrypt(encryptedPassword);
    System.out.println("Decrypted password: " + decryptedPassword);
}

private static String encrypt(String property) 
throws GeneralSecurityException, UnsupportedEncodingException {
    SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
    SecretKey key = keyFactory.generateSecret(new PBEKeySpec(PASSWORD));
    Cipher pbeCipher = Cipher.getInstance("PBEWithMD5AndDES");
    pbeCipher.init(Cipher.ENCRYPT_MODE, key, new PBEParameterSpec(SALT, 20));
    return base64Encode(pbeCipher.doFinal(property.getBytes("UTF-8")));
}

private static String base64Encode(byte[] bytes) {
    // NB: This class is internal, and you probably should use another impl
    return new BASE64Encoder().encode(bytes);
}

private static String decrypt(String property) 
throws GeneralSecurityException,       IOException {
    SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
    SecretKey key = keyFactory.generateSecret(new PBEKeySpec(PASSWORD));
    Cipher pbeCipher = Cipher.getInstance("PBEWithMD5AndDES");
    pbeCipher.init(Cipher.DECRYPT_MODE, key, new PBEParameterSpec(SALT, 20));
    return new String(pbeCipher.doFinal(base64Decode(property)), "UTF-8");
}

private static byte[] base64Decode(String property) throws IOException {
    // NB: This class is internal, and you probably should use another impl
    return new BASE64Decoder().decodeBuffer(property);
}

}

例外は次のとおりです。

Exception in thread "main" java.lang.Exception: java.security.InvalidAlgorithmParameterException: Salt must be 8 bytes long 
  at TransactionTokenUtility.encrypt(TransactionTokenUtility.java:80) 
  at TransactionTokenUtility.generateToken(TransactionTokenUtility.java:144) 
  at TransactionTokenUtility.main(TransactionTokenUtility.java:51) 
Caused by: java.security.InvalidAlgorithmParameterException: Salt must be 8 bytes long 
  at com.sun.crypto.provider.SunJCE_ab.a(DashoA13*..) 
  at com.sun.crypto.provider.PBEWithMD5AndDESCipher.engineInit(DashoA13*..) 
4

1 に答える 1

2

答えは、古い v1.5 PKCS#5 標準および PBKDF1 に従って、ソルトには正確に 8 つのランダムなオクテット (読み取り: バイト) が含まれている必要があるということです。Oracle Java の実装 (2002 年から!) は、この標準に従っています。これは、Oracle から入手できるソース コードを使用して確認できます (実際に確認されています)。

8 オクテットを必要とする規格:

  • PKCS#5 v1.5
  • PKCS#5 v2.0 以降の PBKDF バージョン 1 (PKCS#5 との互換性のために定義)

最低 8 オクテットを必要とする標準 (推奨):

  • PKCS#5 標準 v2.0 以降の PBKDF2

最善の方法は、PBKDF2 に移行することです。より安全な (NIST が承認した) アルゴリズムがあり、salt の長さに関する柔軟性が高くなります。

PKCS#5 のソルトに関する章 (第 4 章) では、最小セキュリティ要件として最低 8 オクテットについて述べていることに注意してください。ただし、これは正確に 8 オクテットを定義する PBKDF1 の定義によって却下されます。

于 2013-06-07T11:06:48.423 に答える