2012-12-07 1 views
0

다른 암호화 키를 생성하기 위해 PBE를 사용하고 싶습니다.PBE 키 생성기에서 해시 값을 얻는 방법

public SecretKey generateKey(String Ags) throws Exception { 
    // make password 
    PBEKeySpec keySpec = new PBEKeySpec(this.password.toCharArray(),this.salt,20,56); 

    SecretKeyFactory keyFactory = SecretKeyFactory 
      .getInstance("PBE"); 
    SecretKey key = keyFactory.generateSecret(keySpec); 
    System.out.println(); 

    /* 
    KeyGenerator kg = KeyGenerator.getInstance("AES"); 
    kg.init(k); 
    // 
    SecretKey FINAL_key = new SecretKeySpec(key.getEncoded(), "AES"); 
    */ 
    return null; 
} 

내 기본적인 생각은 AES 키를 생성하기 위해, 10 바이트를 가정 해 봅시다, 처음 몇 바이트를 얻을 후 처음 PBE 키를 생성 PBEKeySpecSecretKeyFactory를 사용하고 있습니다. 그러나 인터넷 검색 후, 나는 여전히 최종 키를 얻는 방법을 모르겠다. byte[]. key.getEncoded()은 입력 암호를 ​​알려줍니다. 최종 키를 byte[]으로 가져 오려면 어떻게해야합니까?

답변

0

내가 알고있는 한 documentation을 읽으면 AES 비밀 키를 만들고 싶다면 적어도 128 비트의 키로 알고리즘을 입력해야한다는 것을 이해합니다.

SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES"); 

그래서 대신에 당신은 또한 SHA를 공급하기 위해 PBE 키를 사용하고있는 바이트를 얻을 수 있습니다

byte[] key = (Password+Username).getBytes("UTF-8"); // depends on your implementation 
MessageDigest sha = MessageDigest.getInstance("SHA-1"); 
key = sha.digest(key); 
key = Arrays.copyOf(key, 16); // AES uses 16 byte of key as a parameter (?) 

을 사용할 수 있습니다, 당신은 왜 PBE 키에서 128 개 비트를 얻기 주장 해 않는 키 생성 그런 식으로. Okey가 내 보안 폴더의 전체 작동 코드입니다. 문제가 해결되었습니다. 저에게 도움이되었으므로 언제든지 질문하십시오. 아래 코드에서 키가 pbeKeySpec을 사용하여 생성 된 것을 확인할 수 있습니다. 그러나 코드를 검토 할 때 나는 무엇이 잘못되었는지 알 수 없습니다.

public void testPBEWithSHA1AndAES() throws Exception { 
     String password = "test"; 
     String message = "Hello World!"; 

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

     int count = 1024; 
     // int keyLength = 256; 
     int keyLength = 128; 

     String cipherAlgorithm = "AES/CBC/PKCS5Padding"; 
     String secretKeyAlgorithm = "PBKDF2WithHmacSHA1"; 
     SecretKeyFactory keyFac = SecretKeyFactory 
       .getInstance(secretKeyAlgorithm); 
     PBEKeySpec pbeKeySpec = new PBEKeySpec(password.toCharArray(), salt, 
       count, keyLength); 
     SecretKey tmp = keyFac.generateSecret(pbeKeySpec); 
     SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES"); 
     Cipher ecipher = Cipher.getInstance(cipherAlgorithm); 
     ecipher.init(Cipher.ENCRYPT_MODE, secret, new IvParameterSpec(iv)); 

     // decrypt 
     keyFac = SecretKeyFactory.getInstance(secretKeyAlgorithm); 
     pbeKeySpec = new PBEKeySpec(password.toCharArray(), salt, count, 
       keyLength); 
     tmp = keyFac.generateSecret(pbeKeySpec); 
     secret = new SecretKeySpec(tmp.getEncoded(), "AES"); 
     // AlgorithmParameters params = ecipher.getParameters(); 
     // byte[] iv = params.getParameterSpec(IvParameterSpec.class).getIV(); 
     Cipher dcipher = Cipher.getInstance(cipherAlgorithm); 
     dcipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(iv)); 

     byte[] encrypted = ecipher.doFinal(message.getBytes()); 
     byte[] decrypted = dcipher.doFinal(encrypted); 
     assertEquals(message, new String(decrypted)); 

     ByteArrayOutputStream out = new ByteArrayOutputStream(); 
     CipherOutputStream cipherOut = new CipherOutputStream(out, ecipher); 
     cipherOut.write(message.getBytes()); 
     StreamUtils.closeQuietly(cipherOut); 
     byte[] enc = out.toByteArray(); 

     ByteArrayInputStream in = new ByteArrayInputStream(enc); 
     CipherInputStream cipherIn = new CipherInputStream(in, dcipher); 
     ByteArrayOutputStream dec = new ByteArrayOutputStream(); 
     StreamUtils.copy(cipherIn, dec); 
     assertEquals(message, new String(dec.toByteArray())); 
    } 
+0

이 실행할 수 있습니다, 그러나, tmp.getEncoded() 항상 내가 아무리 소금이 무엇인지 내 질문에 언급하지 않고, 같은 비밀번호로 동일하다 같은 값을 반환합니다. – panda