web-dev-qa-db-ja.com

秘密鍵の文字列への変換とその逆

キーを生成しており、DBに保存する必要があるため、キーを文字列に変換しますが、文字列からキーを取得します。これを達成する可能な方法は何ですか?

私のコードは、

SecretKey key = KeyGenerator.getInstance("AES").generateKey();
String stringKey=key.toString();
System.out.println(stringKey);

どうすれば文字列からキーを取得できますか?

88
Princeyesuraj

SecretKeyをバイト配列(byte[])に変換してから、Base64でStringにエンコードできます。 SecretKeyに戻すには、Base64が文字列をデコードし、SecretKeySpecで使用して元のSecretKeyを再構築します。

Java 8の場合

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"); 

Java 7以前(Androidを含む):

注I:Base64エンコード/デコード部分をスキップして、SQLiteにbyte[]を保存することができます。ただし、Base64エンコード/デコードの実行は高価な操作ではなく、ほとんどすべてのDBに問題なく文字列を保存できます。

注II:以前のJavaバージョンでは、Java.langまたはJava.utilのいずれかにBase64が含まれていませんパッケージ。ただし、 Apache Commons CodecBouncy 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");
236
Jabari

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;
}
4
Maarten Bodewes

.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

1
luis.espinal

実際、ルイスが提案したことは私にはうまくいきませんでした。別の方法を見つけなければなりませんでした。これは私を助けたものです。あなたにも役立つかもしれません。リンク:

  1. * .getEncoded(): https://docs.Oracle.com/javase/7/docs/api/Java/security/Key.html

  2. エンコーダー情報: https://docs.Oracle.com/javase/8/docs/api/Java/util/Base64.Encoder.html

  3. デコーダー情報: 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");
1
Revanth Kumar

SecretKeySpecをStringに、またはその逆に変換するSecretKeySpecgetEncoded()メソッドを使用するとbyteArrayが得られ、encodeToString()を使用してBase64オブジェクトのstringSecretKeySpec値を取得できます。

SecretKeySpecStringに変換している間、Base64decode()を使用すると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");
0
anand krish