相当于openssl中的PasswordDeriveBytes

我有C#代码如下:

private static string password = "Password"; private static string salt = "SALT"; private static string hashAlgorithm = "SHA1"; private static int iterations = 2; var saltValueBytes = Encoding.UTF8.GetBytes(salt); var passwordKey = new PasswordDeriveBytes(password, saltValueBytes, hashAlgorithm, iterations) ... 

我需要在Mac中实现相同的function,我才知道Opnessl实现了相关的方法(即libcrypto)。

Opnessl对上述代码的等效方法是什么?

这显示了如何使用OpenSSL实现PBKDF1,根据文档是PasswordDeriveBytes使用的算法。

 #include  #include  #include  void pbkdf1(const char *password, const char *salt, long iter, unsigned char dk[SHA_DIGEST_LENGTH]) { size_t pwlen = strlen(password); size_t dlen = pwlen + 8; unsigned char *buf; if (dlen > SHA_DIGEST_LENGTH) buf = malloc(dlen); else buf = malloc(SHA_DIGEST_LENGTH); memcpy(buf, password, pwlen); strncpy((char *)buf + pwlen, salt, 8); while (iter-- > 0) { SHA1(buf, dlen, buf); dlen = SHA_DIGEST_LENGTH; } memcpy(dk, buf, SHA_DIGEST_LENGTH); free(buf); } 

OpenSSL实现了PBKDF2,.NET公开为Rfc2898DeriveBytesPasswordDeriveBytes使用(根据.NET 4文档 )“PBKDF1算法的扩展”。 OpenSSL不会暴露PBKDF1(谁知道问题的’扩展’是什么)。

如果可能的话,使用PBKDF2(又名Rfc2898DeriveBytes )可以为您节省很多问题。

这是单声道源代码的c ++快速和脏的转换,以执行GetBytes(X),其中X可以大于散列的大小。 如你所见,我只实现了SHA1版本……

 #include  #include  #include  #define SHA1_BYTES_LEN 20 using namespace std; namespace DeriveKeys { class PasswordDeriveBytes { private: unsigned char* password; int pass_len; unsigned char* salt; int salt_len; int IterationCount; int state; unsigned char* initial; unsigned char* output; unsigned int output_len; unsigned int position; int hashnumber; public: PasswordDeriveBytes(unsigned char* password, unsigned char* salt, int iterations) { Prepare(password, salt, iterations); } private: string convertInt(int number) { if (number == 0) return "0"; string temp=""; string returnvalue=""; while (number>0) { temp+=number%10+48; number/=10; } for (unsigned int i=0; ipassword = new unsigned char[pass_len]; memcpy(this->password,password,pass_len); //memcpy((char *)this->password, (const char*)password, pass_len); this->pass_len = pass_len; //(unsigned char*)password.Clone(); this->salt = new unsigned char[salt_len]; //strncpy((char *)this->salt, (const char*)salt, salt_len); memcpy(this->salt,salt,salt_len); this->salt_len = salt_len; this->IterationCount = iterations; state = 0; } public: unsigned char* GetBytes(int cb) { if (cb < 1) return NULL; if (state == 0) { // it's now impossible to change the HashName, Salt // and IterationCount Reset(); state = 1; } unsigned char* result = new unsigned char[cb]; int cpos = 0; // the initial hash (in reset) + at least one iteration int iter = IterationCount-1; if (iter < 1) { iter = 1; } // start with the PKCS5 key if (this->output == NULL) { // calculate the PKCS5 key this->output = initial; this->output_len = SHA1_BYTES_LEN; // generate new key material for (int i = 0; i < iter - 1; i++) { SHA1((const unsigned char*)this->output,this->output_len,this->output); this->output_len = SHA1_BYTES_LEN; } } while (cpos < cb) { unsigned char* output2 = new unsigned char[SHA1_BYTES_LEN]; unsigned int output2_len = SHA1_BYTES_LEN; if (hashnumber == 0) { SHA1((const unsigned char*)this->output,this->output_len,output2); output2_len = SHA1_BYTES_LEN; } else if (hashnumber < 1000) { string n = convertInt(hashnumber); output2 = new unsigned char[this->output_len + n.length()]; output2_len = this->output_len + n.length(); for (unsigned int j = 0; j < n.length(); j++) output2[j] = (unsigned char)(n[j]); memcpy(output2 + n.length(),this->output,this->output_len); SHA1((const unsigned char*)output2,output2_len,output2); output2_len = SHA1_BYTES_LEN; } else { return NULL; } int rem = this->output_len - this->position; int l = cb - cpos; if (l > rem) { l = rem; } memcpy(result + cpos, output2 + this->position, l); cpos += l; this->position += l; while (this->position >= output2_len) { this->position -= output2_len; this->hashnumber++; } } return result; } void Reset() { this->state = 0; this->position = 0; this->hashnumber = 0; this->initial = new unsigned char[SHA1_BYTES_LEN]; this->output = NULL; this->output_len = 0; if (this->salt != NULL) { unsigned char* rv = new unsigned char[this->pass_len + this->salt_len]; memcpy(rv,this->password, this->pass_len); memcpy(rv + this->pass_len, this->salt, this->salt_len); SHA1((const unsigned char*)rv,this->pass_len + this->salt_len, initial); } else { SHA1((const unsigned char*)this->password,this->pass_len,initial); } } }; }