2016-03-02 2 views
0

J'ai besoin d'écrire un module Apache qui crypte les données et j'ai besoin de décrypter les données dans Java.Algorithme exact utilisé par apr_crypto_passphrase

Jusqu'à présent, j'ai réussi à chiffrer les données du côté apache, mais je ne peux pas trouver la clé utilisée pour le chiffrement car elle est cachée dans un apr_crypto_passphrase et stockée dans un apr_crypto_key_t, qui est un type incomplet.

Le documentation mentionne qu'il utilise par défaut "l'algorithme PBKDF2", mais ne précise pas quelle saveur, par ex. PBKDF2WithHmacSHA256, ni ce que signifie "par défaut", et je ne vois pas comment modifier l'algorithme. J'utilise le pilote OpenSSL et je veux utiliser AES 128 en mode CBC.

Comment puis-je obtenir (ou définir) la clé utilisée efficacement, ou comment puis-je calculer cette clé dans Java.

+0

C'est un projet Apache, donc vous pouvez juste regarder dans le code source. –

+0

Donc, nous ne posons plus de questions sur les projets open source? ;) Mais vous avez raison et j'envisage aujourd'hui, et si mon travail le permet, je vais essayer de mettre à jour le document. C'est la bonne chose à propos de OOS après tout. C'était la dernière chose que j'ai faite hier et depuis que les docs manquaient je pensais que j'essayais ici, peut-être que quelqu'un le sait et nous l'avons documenté dans un endroit trouvable;) – Mene

+1

Oui, vous pouvez poser des questions sur les projets open source. Je n'ai pas baissé ou mis en minorité, donc c'est une très bonne question, mais je n'ai pas de réponse et je n'ai pas le temps de regarder dans le code source pour fournir une réponse. Si personne ne répond, vous perdrez beaucoup de temps, alors vous pouvez vous regarder. Ne pas oublier de fournir votre propre réponse, quand vous le résoudre. –

Répondre

0

Au moins avec le pilote OpenSSL PBKDF2 avec SHA1 est utilisé (ceci est codé en dur). Ci-dessous sont deux éléments de code qui produisent la même sortie à partir de texte brut, mot de passe, sel, compte d'itération et IV donnés.

C/APR (fonctions référencées peuvent être trouvées dans 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); 

Java:

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

Rappel: ne pas utiliser ces valeurs pour le code productif.