Создать ключ из строки? - PullRequest
10 голосов
/ 02 марта 2012

Мне нужно сгенерировать ключ из строки, чтобы я всегда мог создать один и тот же ключ из одной и той же строки.(В частности, объект Key, так что я могу использовать его для создания Cipher, в свою очередь, для создания SealedObject)

Возможно ли это в Java, и какую комбинацию классов / методов мне следует искать для этого?

Ответы [ 3 ]

17 голосов
/ 02 марта 2012

Для шифрования AES:

SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
KeySpec spec = new PBEKeySpec(password, salt, 65536, 256);
SecretKey tmp = factory.generateSecret(spec);
SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES");

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secret);

byte[] iv = cipher.getParameters().getParameterSpec(IvParameterSpec.class).getIV();
byte[] ciphertext = cipher.doFinal("Hello, World!".getBytes("UTF-8"));

// reinit cypher using param spec
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(iv));

Аналогично для устаревших PBKDF1 и небезопасных DES для связи с устаревшими системами или в учебных целях :

byte[] salt = {
    (byte)0xc7, (byte)0x73, (byte)0x21, (byte)0x8c,
    (byte)0x7e, (byte)0xc8, (byte)0xee, (byte)0x99
};

int count = 20;

PBEParameterSpec pbeParamSpec = new PBEParameterSpec(salt, count);
PBEKeySpec pbeKeySpec = new PBEKeySpec(password.toCharArray());
SecretKeyFactory keyFac = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
SecretKey pbeKey = keyFac.generateSecret(pbeKeySpec);

Cipher cipher = Cipher.getInstance("PBEWithMD5AndDES");
cipher.init(Cipher.ENCRYPT_MODE, pbeKey, pbeParamSpec);

SealedObject sealed = new SealedObject(object, cipher);
...

Обратите внимание, что число итераций также слишком мало в последнем примере.

4 голосов
/ 03 марта 2012

Вы хотите использовать для этого PBKDF2 или bcrypt .Первый более широко используется в моем опыте.На основании этого комментария создается впечатление, что Java поддерживает это.

SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
KeySpec spec = new PBEKeySpec(password, salt, 65536, 256);
SecretKey tmp = factory.generateSecret(spec);
SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES");
0 голосов
/ 02 марта 2012

Этого можно добиться с помощью шифрования Java.

Сначала вам понадобятся две банки:

  1. bcmail-jdk16-1.46.jar
  2. bcprov-jdk16-1.46.jar

Вот полный пример того, как Стандарт шифрования данных в Java:

import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;

import org.bouncycastle.util.encoders.Base64;


public class KeyGen {
    private SecretKey key;
    private Cipher ecipher;
    private Cipher dcipher;
    private static KeyGen keyGen;

    private KeyGen() throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException{
        key = KeyGenerator.getInstance("DES").generateKey();
        ecipher = Cipher.getInstance("DES");
        dcipher = Cipher.getInstance("DES");
        ecipher.init(Cipher.ENCRYPT_MODE, key);
        dcipher.init(Cipher.DECRYPT_MODE, key);
    }

    public static KeyGen getInstance() throws NoSuchAlgorithmException, InvalidKeyException, NoSuchPaddingException {
        if(keyGen == null) {
            keyGen = new KeyGen();
        }
        return keyGen;
    }

    public String encrypt(String str) throws UnsupportedEncodingException, IllegalBlockSizeException, BadPaddingException {
        byte[] utf8 = str.getBytes("UTF8");
        byte[] enc = ecipher.doFinal(utf8);
        return new String(Base64.encode(enc));
    }

    public String decrypt(String str) throws IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException {
        byte[] dec = Base64.decode(str);
        byte[] utf8 = dcipher.doFinal(dec);
        return new String(utf8, "UTF8");
    }

    public static void main(String[] args) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, UnsupportedEncodingException, IllegalBlockSizeException, BadPaddingException {
        KeyGen keyGen = KeyGen.getInstance();
        String string = "JOYMAA";
        String enc = keyGen.encrypt(string);
        System.out.println(enc);
        String dec = keyGen.decrypt(enc);
        System.out.println(dec);
    }
}

Использование:

KeyGen keyGen = KeyGen.getInstance();
String string = "JOYMAA";
String enc = keyGen.encrypt(string);
System.out.println(enc);
String dec = keyGen.decrypt(enc);
System.out.println(dec);

Надеюсь, это поможет вам.

...