Đây là một phiên bản dành cho mbedTLS/SSL Polar - kiểm tra và làm việc.
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;
}
Tuyệt vời! – Tudorizer
điều này đã cứu mạng tôi. tôi không thể lấy khóa của openssl và iv bằng cách sử dụng cụm từ mật khẩu và muối (trong ios). sau khi nhúng các thư viện openssl vào dự án của tôi, tôi đã có thể sử dụng nó. –
Có thực hiện chức năng này hoặc tương tự trong crypto ++ không? – goji