2012-03-02 38 views
8

Tôi cần tạo một Khóa từ một chuỗi, sao cho tôi luôn có thể tạo cùng một khóa từ cùng một chuỗi. (Cụ thể là đối tượng Key, để tôi có thể sử dụng nó để tạo ra một Cipher để tạo ra một SealedObject)Tạo khóa từ chuỗi?

Điều này có thể thực hiện được trong Java, và tôi nên xem xét kết hợp lớp/phương pháp nào?

+0

sẽ không 'hashCode()' làm gì cho bạn? nếu không - tại sao? – amit

+0

http://en.wikipedia.org/wiki/Java_hashCode()#The_java.lang.String_hash_function – JProgrammer

+0

Không xa như tôi biết, vì tôi đang cố gắng tạo một SealedObject để gói gọn một đối tượng để truyền: Tôi không cố gắng làm xáo trộn chuỗi chữ thô thành một băm, tôi đang cố tạo một Khóa (đối tượng) –

Trả lời

16

Đối với mã hóa 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)); 

Tương tự như vậy đối với các phản PBKDF1 và DES không an toàn để giao tiếp với hệ thống di sản hoặc mục đích học tập:

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

Lưu ý rằng tính lặp đi lặp lại quá thấp như trong ví dụ cuối cùng.

+0

Cảm ơn. Chỉ cần được rõ ràng, nếu tôi thực hiện tương tự ở phía máy chủ với cùng một mật khẩu, nó sẽ tạo ra một mật mã có thể được sử dụng để giải mã SealedObject? –

+0

Đó là chính xác. Miễn là bạn đang sử dụng cùng một thông số kỹ thuật và thông số chính, bạn sẽ có cùng một khóa. –

+4

Điều này sẽ là một câu trả lời tốt hơn nếu bạn loại bỏ nửa đầu. DES hoàn toàn bị phá vỡ ngày hôm nay, và nó là nguy hiểm để sử dụng nó ngay cả khi một ví dụ (mọi người có thể sao chép nó mà không biết rằng nó là không an toàn). –

0

Bạn có thể thực hiện điều này bằng Mã hóa Java.

Lúc đầu, bạn cần hai lọ:

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

Dưới đây là ví dụ đầy đủ về cách Data Encryption Standard trong 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); 
    } 
} 

Cách sử dụng:

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

Hy vọng điều này sẽ giúp bạn.

+0

DES có thể không giúp được ai nữa ... –

+0

Không mã hóa chế độ ECB. Có một lớp có tên là 'KeyGen' thực hiện mã hóa/giải mã không cung cấp nhiều hy vọng. –

4

Bạn muốn sử dụng PBKDF2 hoặc bcrypt cho việc này. Cái cũ được sử dụng rộng rãi hơn trong kinh nghiệm của tôi. Nó xuất hiện, dựa trên điều này comment, mà java không hỗ trợ này.

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"); 
Các vấn đề liên quan