相当于openssl中的PasswordDeriveBytes

发布于 2024-09-25 20:34:36 字数 496 浏览 2 评论 0原文

我的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中实现相同的功能,我知道Opnessl实现了相关方法(即libcrypto)。

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

I have C# code as below:


        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)
...

I need to implement the same in Mac, I came to know that Opnessl implements related methods(i.e. libcrypto).

What is the equivalent method in Opnessl to above code?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

够运 2024-10-02 20:34:36

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

#include <string.h>
#include <stdlib.h>
#include <openssl/sha.h>

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);
}

This shows how to implement PBKDF1 with OpenSSL, which according to the documentation is the algorithm used by PasswordDeriveBytes.

#include <string.h>
#include <stdlib.h>
#include <openssl/sha.h>

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);
}
一个人的夜不怕黑 2024-10-02 20:34:36

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

如果可能的话,使用 PBKDF2(又名 Rfc2898DeriveBytes)将为您避免很多问题。

OpenSSL implements PBKDF2, which .NET exposes as Rfc2898DeriveBytes. PasswordDeriveBytes uses (according to the .NET 4 docs) "an extension of the PBKDF1 algorithm". PBKDF1 is not exposed by OpenSSL (and who knows what the 'extension' in question may be).

Using PBKDF2 (aka Rfc2898DeriveBytes) if possible will save you a lot of problems here.

︶ ̄淡然 2024-10-02 20:34:36

这是 mono 源代码 用于执行 GetBytes(X),其中 X 可以大于散列的大小。正如你所看到的,我只实现了 SHA1 版本......

#include <iostream>
#include <string.h>
#include <openssl/sha.h>

#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; i<temp.length(); i++)
        returnvalue+=temp[temp.length()-i-1];
    return returnvalue;
    }

    void Prepare(unsigned char* password, unsigned char* salt, int iterations)
    {
    if (password == NULL)
        return;

    Prepare(password, strlen((const char*)password), salt, strlen((const char*)salt), iterations);
    }

    void Prepare(unsigned char* password, int pass_len, unsigned char* salt, int salt_len, int iterations)
    {
    if (password == NULL)
        return;

    this->password = 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);
    }
    }
};
}

This is a c++ quick and dirty translation of the mono source code to perform GetBytes(X) where X can be greater than the size of the hash. As you can see I'v implemented only the SHA1 version...

#include <iostream>
#include <string.h>
#include <openssl/sha.h>

#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; i<temp.length(); i++)
        returnvalue+=temp[temp.length()-i-1];
    return returnvalue;
    }

    void Prepare(unsigned char* password, unsigned char* salt, int iterations)
    {
    if (password == NULL)
        return;

    Prepare(password, strlen((const char*)password), salt, strlen((const char*)salt), iterations);
    }

    void Prepare(unsigned char* password, int pass_len, unsigned char* salt, int salt_len, int iterations)
    {
    if (password == NULL)
        return;

    this->password = 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);
    }
    }
};
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文