キーを生成しており、DBに保存する必要があるため、キーを文字列に変換しますが、文字列からキーを取得します。これを達成する可能な方法は何ですか?
私のコードは、
SecretKey key = KeyGenerator.getInstance("AES").generateKey();
String stringKey=key.toString();
System.out.println(stringKey);
どうすれば文字列からキーを取得できますか?
SecretKey
をバイト配列(byte[]
)に変換してから、Base64でString
にエンコードできます。 SecretKey
に戻すには、Base64が文字列をデコードし、SecretKeySpec
で使用して元のSecretKey
を再構築します。
SecretKey to String:
// create new key
SecretKey secretKey = KeyGenerator.getInstance("AES").generateKey();
// get base64 encoded version of the key
String encodedKey = Base64.getEncoder().encodeToString(secretKey.getEncoded());
SecretKeyの文字列:
// decode the base64 encoded string
byte[] decodedKey = Base64.getDecoder().decode(encodedKey);
// rebuild key using SecretKeySpec
SecretKey originalKey = new SecretKeySpec(decodedKey, 0, decodedKey.length, "AES");
注I:Base64エンコード/デコード部分をスキップして、SQLiteにbyte[]
を保存することができます。ただし、Base64エンコード/デコードの実行は高価な操作ではなく、ほとんどすべてのDBに問題なく文字列を保存できます。
注II:以前のJavaバージョンでは、Java.lang
またはJava.util
のいずれかにBase64が含まれていませんパッケージ。ただし、 Apache Commons Codec 、 Bouncy Castle 、または Guava のコーデックを使用できます。
SecretKey to String:
// CREATE NEW KEY
// GET ENCODED VERSION OF KEY (THIS CAN BE STORED IN A DB)
SecretKey secretKey;
String stringKey;
try {secretKey = KeyGenerator.getInstance("AES").generateKey();}
catch (NoSuchAlgorithmException e) {/* LOG YOUR EXCEPTION */}
if (secretKey != null) {stringKey = Base64.encodeToString(secretKey.getEncoded(), Base64.DEFAULT)}
SecretKeyの文字列:
// DECODE YOUR BASE64 STRING
// REBUILD KEY USING SecretKeySpec
byte[] encodedKey = Base64.decode(stringKey, Base64.DEFAULT);
SecretKey originalKey = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");
fail fastの関数を作成することの楽しさを示すために、次の3つの関数を作成しました。
1つはAESキーを作成し、1つはそれをエンコードし、もう1つはそれをデコードして戻します。これら3つのメソッドは、Java 8で使用できます(内部クラスまたは外部の依存関係なし):
public static SecretKey generateAESKey(int keysize)
throws InvalidParameterException {
try {
if (Cipher.getMaxAllowedKeyLength("AES") < keysize) {
// this may be an issue if unlimited crypto is not installed
throw new InvalidParameterException("Key size of " + keysize
+ " not supported in this runtime");
}
final KeyGenerator keyGen = KeyGenerator.getInstance("AES");
keyGen.init(keysize);
return keyGen.generateKey();
} catch (final NoSuchAlgorithmException e) {
// AES functionality is a requirement for any Java SE runtime
throw new IllegalStateException(
"AES should always be present in a Java SE runtime", e);
}
}
public static SecretKey decodeBase64ToAESKey(final String encodedKey)
throws IllegalArgumentException {
try {
// throws IllegalArgumentException - if src is not in valid Base64
// scheme
final byte[] keyData = Base64.getDecoder().decode(encodedKey);
final int keysize = keyData.length * Byte.SIZE;
// this should be checked by a SecretKeyFactory, but that doesn't exist for AES
switch (keysize) {
case 128:
case 192:
case 256:
break;
default:
throw new IllegalArgumentException("Invalid key size for AES: " + keysize);
}
if (Cipher.getMaxAllowedKeyLength("AES") < keysize) {
// this may be an issue if unlimited crypto is not installed
throw new IllegalArgumentException("Key size of " + keysize
+ " not supported in this runtime");
}
// throws IllegalArgumentException - if key is empty
final SecretKeySpec aesKey = new SecretKeySpec(keyData, "AES");
return aesKey;
} catch (final NoSuchAlgorithmException e) {
// AES functionality is a requirement for any Java SE runtime
throw new IllegalStateException(
"AES should always be present in a Java SE runtime", e);
}
}
public static String encodeAESKeyToBase64(final SecretKey aesKey)
throws IllegalArgumentException {
if (!aesKey.getAlgorithm().equalsIgnoreCase("AES")) {
throw new IllegalArgumentException("Not an AES key");
}
final byte[] keyData = aesKey.getEncoded();
final String encodedKey = Base64.getEncoder().encodeToString(keyData);
return encodedKey;
}
.toString()
を使用したくありません。
SecretKeyは、Serializableから継承するJava.security.Keyを継承することに注意してください。したがって、ここでのキー(しゃれはありません)は、キーをByteArrayOutputStreamにシリアル化し、byte []配列を取得してdbに格納することです。逆のプロセスは、dbからbyte []配列を取得し、byte []配列のByteArrayInputStreamを作成し、SecretKeyを逆シリアル化することです...
...またはもっと簡単に、Java.security.Key(SecretKeyの親インターフェース)から継承された.getEncoded()
メソッドを使用します。このメソッドは、Key/SecretKeyからエンコードされたbyte []配列を返します。これは、データベースに格納したり、データベースから取得したりできます。
これはすべて、SecretKey実装がエンコードをサポートしていることを前提としています。それ以外の場合、getEncoded()
はnullを返します。
Key/SecretKey javadocs(Googleページの最初から利用可能)をご覧ください:
http://download.Oracle.com/javase/6/docs/api/Java/security/Key.html
または、これはCodeRanchから(同じGoogle検索でも見つかりました):
http://www.coderanch.com/t/429127/Java/java/Convertion-between-SecretKey-String-or
実際、ルイスが提案したことは私にはうまくいきませんでした。別の方法を見つけなければなりませんでした。これは私を助けたものです。あなたにも役立つかもしれません。リンク:
* .getEncoded(): https://docs.Oracle.com/javase/7/docs/api/Java/security/Key.html
エンコーダー情報: https://docs.Oracle.com/javase/8/docs/api/Java/util/Base64.Encoder.html
デコーダー情報: https://docs.Oracle.com/javase/8/docs/api/Java/util/Base64.Decoder.html
コードスニペット:エンコード用:
String temp = new String(Base64.getEncoder().encode(key.getEncoded()));
デコードの場合:
byte[] encodedKey = Base64.getDecoder().decode(temp);
SecretKey originalKey = new SecretKeySpec(encodedKey, 0, encodedKey.length, "DES");
SecretKeySpecをStringに、またはその逆に変換するSecretKeySpec
でgetEncoded()
メソッドを使用するとbyteArray
が得られ、encodeToString()
を使用してBase64
オブジェクトのstring
のSecretKeySpec
値を取得できます。
SecretKeySpec
をString
に変換している間、Base64
でdecode()
を使用するとbyteArray
が得られます。SecretKeySpec
のインスタンスを作成して、byteArray
としてparamsを使用してSecretKeySpec
を再現できます。
String mAesKey_string;
SecretKeySpec mAesKey= new SecretKeySpec(secretKey.getEncoded(), "AES");
//SecretKeySpec to String
byte[] byteaes=mAesKey.getEncoded();
mAesKey_string=Base64.encodeToString(byteaes,Base64.NO_WRAP);
//String to SecretKeySpec
byte[] aesByte = Base64.decode(mAesKey_string, Base64.NO_WRAP);
mAesKey= new SecretKeySpec(aesByte, "AES");