从字符串生成密钥?

我需要从字符串生成一个Key,这样我总是可以从同一个字符串创建相同的键。 (特别是一个Key对象,这样我就可以用它来创建一个Cipher来创建一个SealedObject)

这在Java中是否可行,我应该考虑使用哪种类/方法组合?

对于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实现此目的。

起初你需要两个jar子:

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

希望这会帮助你。