Создать ключ из строки?

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

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

3 ответа

Для шифрования 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);
...

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


Вы хотите использовать 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");


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

Сначала вам нужны две банки:

Вот полный пример того, как Стандарт шифрования данных в 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);

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

licensed under cc by-sa 3.0 with attribution.