verificar instalar crear comandos certificado c openssl cryptography password-encryption kdf

instalar - Contraseña para la función de tecla compatible con los comandos de OpenSSL?



openssl pkcs12 (3)

Si alguien está buscando implementar lo mismo en SWIFT, convertí el EVP_BytesToKey la EVP_BytesToKey

/* - parameter keyLen: keyLen - parameter ivLen: ivLen - parameter digest: digest e.g "md5" or "sha1" - parameter salt: salt - parameter data: data - parameter count: count - returns: key and IV respectively */ open static func evpBytesToKey(_ keyLen:Int, ivLen:Int, digest:String, salt:[UInt8], data:Data, count:Int)-> [[UInt8]] { let saltData = Data(bytes: UnsafePointer<UInt8>(salt), count: Int(salt.count)) var both = [[UInt8]](repeating: [UInt8](), count: 2) var key = [UInt8](repeating: 0,count: keyLen) var key_ix = 0 var iv = [UInt8](repeating: 0,count: ivLen) var iv_ix = 0 var nkey = keyLen; var niv = ivLen; var i = 0 var addmd = 0 var md:Data = Data() var md_buf:[UInt8] while true { addmd = addmd + 1 md.append(data) md.append(saltData) if(digest=="md5"){ md = NSData(data:md.md5()) as Data }else if (digest == "sha1"){ md = NSData(data:md.sha1()) as Data } for _ in 1...(count-1){ if(digest=="md5"){ md = NSData(data:md.md5()) as Data }else if (digest == "sha1"){ md = NSData(data:md.sha1()) as Data } } md_buf = Array (UnsafeBufferPointer(start: md.bytes, count: md.count)) // md_buf = Array(UnsafeBufferPointer(start: md.bytes.bindMemory(to: UInt8.self, capacity: md.count), count: md.length)) i = 0 if (nkey > 0) { while(true) { if (nkey == 0){ break } if (i == md.count){ break } key[key_ix] = md_buf[i]; key_ix = key_ix + 1 nkey = nkey - 1 i = i + 1 } } if (niv > 0 && i != md_buf.count) { while(true) { if (niv == 0){ break } if (i == md_buf.count){ break } iv[iv_ix] = md_buf[i] iv_ix = iv_ix + 1 niv = niv - 1 i = i + 1 } } if (nkey == 0 && niv == 0) { break } } both[0] = key both[1] = iv return both }

Yo uso CryptoSwift para el hash. Esta es una forma mucho más limpia ya que las manzanas no recomiendan OpenSSL en iOS

ACTUALIZACIÓN: Swift 3

Por ejemplo, el comando:

openssl enc -aes-256-cbc -a -in test.txt -k pinkrhino -nosalt -p -out openssl_output.txt

produce algo como:

key = 33D890D33F91D52FC9B405A0DDA65336C3C4B557A3D79FE69AB674BE82C5C3D2 iv = 677C95C475C0E057B739750748608A49

¿Cómo se genera esa clave? (El código C como respuesta sería demasiado impresionante como para preguntar :)) Además, ¿cómo se genera el iv?

Parece una especie de maleficio para mí.


Aquí hay una versión para mbedTLS / Polar SSL - probado y en funcionamiento.

typedef int bool; #define false 0 #define true (!false) //------------------------------------------------------------------------------ static bool EVP_BytesToKey( const unsigned int nDesiredKeyLen, const unsigned char* salt, const unsigned char* password, const unsigned int nPwdLen, unsigned char* pOutKey, unsigned char* pOutIV ) { // This is a re-implemntation of openssl''s password to key & IV routine for mbedtls. // (See openssl apps/enc.c and /crypto/evp/evp_key.c) It is not any kind of // standard (e.g. PBKDF2), and it only uses an interation count of 1, so it''s // pretty crappy. MD5 is used as the digest in Openssl 1.0.2, 1.1 and late // use SHA256. Since this is for embedded system, I figure you know what you''ve // got, so I made it compile-time configurable. // // The signature has been re-jiggered to make it less general. // // See: https://wiki.openssl.org/index.php/Manual:EVP_BytesToKey(3) // And: https://www.cryptopp.com/wiki/OPENSSL_EVP_BytesToKey #define IV_BYTE_COUNT 16 #if BTK_USE_MD5 # define DIGEST_BYTE_COUNT 16 // MD5 #else # define DIGEST_BYTE_COUNT 32 // SHA #endif bool bRet; unsigned char md_buf[ DIGEST_BYTE_COUNT ]; mbedtls_md_context_t md_ctx; bool bAddLastMD = false; unsigned int nKeyToGo = nDesiredKeyLen; // 32, typical unsigned int nIVToGo = IV_BYTE_COUNT; mbedtls_md_init( &md_ctx ); #if BTK_USE_MD5 int rc = mbedtls_md_setup( &md_ctx, mbedtls_md_info_from_type( MBEDTLS_MD_MD5 ), 0 ); #else int rc = mbedtls_md_setup( &md_ctx, mbedtls_md_info_from_type( MBEDTLS_MD_SHA256 ), 0 ); #endif if (rc != 0 ) { fprintf( stderr, "mbedutils_md_setup() failed -0x%04x/n", -rc ); bRet = false; goto exit; } while( 1 ) { mbedtls_md_starts( &md_ctx ); // start digest if ( bAddLastMD == false ) // first time { bAddLastMD = true; // do it next time } else { mbedtls_md_update( &md_ctx, &md_buf[0], DIGEST_BYTE_COUNT ); } mbedtls_md_update( &md_ctx, &password[0], nPwdLen ); mbedtls_md_update( &md_ctx, &salt[0], 8 ); mbedtls_md_finish( &md_ctx, &md_buf[0] ); // // Iteration loop here in original removed as unused by "openssl enc" // // Following code treats the output key and iv as one long, concatentated buffer // and smears as much digest across it as is available. If not enough, it takes the // big, enclosing loop, makes more digest, and continues where it left off on // the last iteration. unsigned int ii = 0; // index into mb_buf if ( nKeyToGo != 0 ) // still have key to fill in? { while( 1 ) { if ( nKeyToGo == 0 ) // key part is full/done break; if ( ii == DIGEST_BYTE_COUNT ) // ran out of digest, so loop break; *pOutKey++ = md_buf[ ii ]; // stick byte in output key nKeyToGo--; ii++; } } if ( nIVToGo != 0 // still have fill up IV && // and ii != DIGEST_BYTE_COUNT // have some digest available ) { while( 1 ) { if ( nIVToGo == 0 ) // iv is full/done break; if ( ii == DIGEST_BYTE_COUNT ) // ran out of digest, so loop break; *pOutIV++ = md_buf[ ii ]; // stick byte in output IV nIVToGo--; ii++; } } if ( nKeyToGo == 0 && nIVToGo == 0 ) // output full, break main loop and exit break; } // outermost while loop bRet = true; exit: mbedtls_md_free( &md_ctx ); return bRet; }


OpenSSL usa la función EVP_BytesToKey . Puede encontrar la llamada en apps/enc.c La utilidad enc utilizaba el resumen de MD5 de forma predeterminada en el Algoritmo de derivación de clave (KDF) si no especificaba un resumen diferente con el argumento -md . Ahora usa SHA-256 de forma predeterminada. Aquí hay un ejemplo de trabajo usando MD5:

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <openssl/evp.h> int main(int argc, char *argv[]) { const EVP_CIPHER *cipher; const EVP_MD *dgst = NULL; unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH]; const char *password = "password"; const unsigned char *salt = NULL; int i; OpenSSL_add_all_algorithms(); cipher = EVP_get_cipherbyname("aes-256-cbc"); if(!cipher) { fprintf(stderr, "no such cipher/n"); return 1; } dgst=EVP_get_digestbyname("md5"); if(!dgst) { fprintf(stderr, "no such digest/n"); return 1; } if(!EVP_BytesToKey(cipher, dgst, salt, (unsigned char *) password, strlen(password), 1, key, iv)) { fprintf(stderr, "EVP_BytesToKey failed/n"); return 1; } printf("Key: "); for(i=0; i<cipher->key_len; ++i) { printf("%02x", key[i]); } printf("/n"); printf("IV: "); for(i=0; i<cipher->iv_len; ++i) { printf("%02x", iv[i]); } printf("/n"); return 0; }

Ejemplo de uso:

gcc b2k.c -o b2k -lcrypto -g ./b2k Key: 5f4dcc3b5aa765d61d8327deb882cf992b95990a9151374abd8ff8c5a7a0fe08 IV: b7b4372cdfbcb3d16a2631b59b509e94

Que genera la misma clave que esta línea de comando de OpenSSL:

openssl enc -aes-256-cbc -k password -nosalt -p < /dev/null key=5F4DCC3B5AA765D61D8327DEB882CF992B95990A9151374ABD8FF8C5A7A0FE08 iv =B7B4372CDFBCB3D16A2631B59B509E94

OpenSSL 1.1.0c cambió el algoritmo de resumen utilizado en algunos componentes internos. Anteriormente, se usaba MD5 y 1.1.0 cambiaba a SHA256. Tenga cuidado de que el cambio no le afecte tanto en EVP_BytesToKey como en comandos como openssl enc .