La situation que j'essaie de résoudre: dans mon application Cocoa, j'ai besoin de crypter une chaîne avec un chiffrement symétrique, de l'envoyer en PHP, et d'avoir ce script décoder les données. Le processus doit fonctionner à l'envers pour renvoyer une réponse (PHP code, Cocoa décode). Il me manque quelque chose car même si je peux obtenir à la fois la clé et le vecteur d'initialisation (iv) identiques dans PHP et Cocoa, le décodage ne fonctionne jamais lorsqu'une application envoie ses données codées à l'autre. Les deux fonctionnent très bien pour coder/décoder leurs propres données (vérifiées pour s'assurer qu'il n'y avait pas de problème avec PEBKAC). Je soupçonne qu'il y a un problème de rembourrage quelque part, je ne le vois tout simplement pas.Cryptage des données dans Cocoa, décodage en PHP (et vice versa)
Mon application de cacao code en utilisant SSCrypto (qui est juste un wrapper pratique autour des fonctions OpenSSL). Le chiffre est Blowfish, le mode est CBC. (Pardonner les fuites de mémoire, le code a été dépouillé à l'essentiel)
NSData *secretText = [@"secretTextToEncode" dataUsingEncoding:NSUTF8StringEncoding];
NSData *symmetricKey = [@"ThisIsMyKey" dataUsingEncoding:NSUTF8StringEncoding];
unsigned char *input = (unsigned char *)[secretText bytes];
unsigned char *outbuf;
int outlen, templen, inlen;
inlen = [secretText length];
unsigned char evp_key[EVP_MAX_KEY_LENGTH] = {"\0"};
int cipherMaxIVLength = EVP_MAX_IV_LENGTH;
EVP_CIPHER_CTX cCtx;
const EVP_CIPHER *cipher = EVP_bf_cbc();
cipherMaxIVLength = EVP_CIPHER_iv_length(cipher);
unsigned char iv[cipherMaxIVLength];
EVP_BytesToKey(cipher, EVP_md5(), NULL, [symmetricKey bytes], [symmetricKey length], 1, evp_key, iv);
NSData *initVector = [NSData dataWithBytes:iv length:cipherMaxIVLength];
EVP_CIPHER_CTX_init(&cCtx);
if (!EVP_EncryptInit_ex(&cCtx, cipher, NULL, evp_key, iv)) {
EVP_CIPHER_CTX_cleanup(&cCtx);
return nil;
}
int ctx_CipherKeyLength = EVP_CIPHER_CTX_key_length(&cCtx);
EVP_CIPHER_CTX_set_key_length(&cCtx, ctx_CipherKeyLength);
outbuf = (unsigned char *)calloc(inlen + EVP_CIPHER_CTX_block_size(&cCtx), sizeof(unsigned char));
if (!EVP_EncryptUpdate(&cCtx, outbuf, &outlen, input, inlen)){
EVP_CIPHER_CTX_cleanup(&cCtx);
return nil;
}
if (!EVP_EncryptFinal(&cCtx, outbuf + outlen, &templen)){
EVP_CIPHER_CTX_cleanup(&cCtx);
return nil;
}
outlen += templen;
EVP_CIPHER_CTX_cleanup(&cCtx);
NSData *cipherText = [NSData dataWithBytes:outbuf length:outlen];
NSString *base64String = [cipherText encodeBase64WithNewlines:NO];
NSString *iv = [initVector encodeBase64WithNewlines:NO];
base64String et iv sont ensuite à PHP qui POSTées tente de le décoder:
<?php
import_request_variables("p", "p_");
if($p_data != "" && $p_iv != "")
{
$encodedData = base64_decode($p_data, true);
$iv = base64_decode($p_iv, true);
$td = mcrypt_module_open(MCRYPT_BLOWFISH, '', MCRYPT_MODE_CBC, '');
$keySize = mcrypt_enc_get_key_size($td);
$key = substr(md5("ThisIsMyKey"), 0, $keySize);
$decodedData = mcrypt_decrypt(MCRYPT_BLOWFISH, $key, $encodedData, MCRYPT_MODE_CBC, $iv);
mcrypt_module_close($td);
echo "decoded: " . $decodedData;
}
?>
decodedData est toujours charabia.
J'ai essayé d'inverser le processus, en envoyant la sortie encodée de PHP vers Cocoa mais EVP_DecryptFinal() échoue, ce qui me porte à croire qu'il y a un problème de remplissage NULL quelque part. J'ai lu et relu les docs PHP et OpenSSL, mais tout est devenu flou maintenant et je n'ai plus d'idées à essayer.
[OpenSSL 1.1.0c a modifié l'algorithme de résumé] (http://stackoverflow.com/q/39637388/608639) utilisé dans certains composants internes. Auparavant, MD5 était utilisé et 1.1.0 passait à SHA256. Veillez à ce que la modification ne vous affecte pas à la fois dans 'EVP_BytesToKey' et dans les commandes comme' openssl enc'. – jww