2016-03-02 55 views
0

我需要編寫一個加密數據的apache模塊,我需要解密java中的數據。apr_crypto_passphrase使用的確切算法

到目前爲止,我設法加密了apache端的數據,但我無法找到有效用於加密的密鑰,因爲它隱藏在apr_crypto_passphrase中,並存儲在apr_crypto_key_t中,這是一種不完整的類型。

documentation提到它使用「默認的PBKDF2算法」,但沒有說明哪種風味,例如PBKDF2WithHmacSHA256,也不是「默認」的意思,也不能看到改變算法的方法。

我正在使用OpenSSL驅動程序,並希望在CBC模式下使用AES 128。

如何獲得(或設置)有效使用的密鑰,或者如何在Java中計算此密鑰。

+0

這是一個Apache項目,所以你可以看看源代碼。 –

+0

因此我們不再詢問開源項目了嗎? ;) 但你說得對,今天我正在研究它,如果我的工作允許,我會嘗試更新文檔。畢竟這是關於OOS的好事。這是我昨天做的最後一件事,因爲文檔缺乏,我認爲我在這裏給它一個鏡頭,也許有人知道它,我們有它在一個可以找到的地方記錄;) – Mene

+1

是的,你可以問關於開源項目。我沒有downvoted或closevoted,所以這是一個非常好的問題,但我沒有答案,沒有時間查看源代碼來提供答案。如果沒有人回答,你會浪費很多時間,所以你可以看看自己。當你解決它時,不要忘記提供你自己的答案。 –

回答

0

至少在OpenSSL驅動程序中使用帶SHA1的PBKDF2(這是硬編碼的)。

下面是兩個代碼片斷,它們從給定的純文本,密碼,salt,迭代計數和IV生成相同的輸出。

C/APR(引用功能可以在testcrypto.c找到):

char *plain_text = apr_pstrdup(pool, "some value"); 
char *passphrase = apr_pstrdup(pool, "some pass"); 

const int salt_len = 9; 
const char salt_in[] = {1, 1, 1, 1, 1, 1, 1, 1, 1}; 

const int iterations = 1000; 

// everything after the 16th byte is ignored for AES 128 
const int iv_len = 16; 
const char iv_in[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; 

unsigned char *cipher_text = NULL; 
apr_size_t cipher_text_len = 0; 
apr_size_t block_size = 0; 
apr_size_t iv_size = 0; 

const apr_crypto_driver_t *driver = get_openssl_driver(r, pool); 
apr_crypto_t *f1 = factory(pool, driver); 

char *salt = apr_palloc(pool, salt_len); 
memcpy(salt, salt_in, salt_len); 

apr_crypto_key_t *crypto_key = NULL; // init to NULL is important, see docs! 

apr_crypto_passphrase(&crypto_key, &iv_size, passphrase, strlen(passphrase), salt, salt_len, APR_KEY_AES_128, APR_MODE_CBC, 1, iterations, f1, pool); 

unsigned char *iv = apr_palloc(pool, iv_len); 
memcpy(iv, iv_in, iv_len); 

encrypt_block(NULL, pool, driver, f1, crypto_key, plain_text, strlen(plain_text), 
          &cipher_text, &cipher_text_len, &iv, &block_size, "KEY_AES_128/MODE_CBC"); 

// Note: b64_len includes spaces for '\0' terminator 
int b64_len = apr_base64_encode_len(cipher_text_len); 
char *b64 = apr_pcalloc(pool, b64_len); 
apr_base64_encode_binary(b64, cipher_text, cipher_text_len); 

爪哇:

/* Derive the key, given passphrase and salt. */ 
final String plainText = "some value"; 
final String passphrase = "some pass"; 
final byte[] salt = {1, 1, 1, 1, 1, 1, 1, 1, 1}; 
final int iterations = 1000; 
byte[] iv = new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; 

SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); 
KeySpec keySpec = new PBEKeySpec(passphrase.toCharArray(), salt, iterations, 128); 
SecretKey tmp = factory.generateSecret(keySpec); 
SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES"); 
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 
cipher.init(Cipher.ENCRYPT_MODE, secret, new IvParameterSpec(iv)); 
byte[] ciphertext = cipher.doFinal(plainText.getBytes("UTF-8")); 

System.out.println(DatatypeConverter.printBase64Binary(ciphertext)); 

提醒:不用於生產代碼中使用這些值。