用于生成密码哈希的 C/C++ 函数(使用 MD5 或其他算法)?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7656219/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
C/C++ function for generating a hash for passwords (using MD5 or another algorithm)?
提问by Josh1billion
I'm looking for a function for C/C++ that behaves identically to PHP's md5() function -- pass in a string, return a one-way hash of that string. I'm also open to other algorithms than md5() if they are as secure (or more secure), reasonably fast, and ideally one-way.
我正在寻找一个 C/C++ 函数,它的行为与 PHP 的 md5() 函数相同——传入一个字符串,返回该字符串的单向哈希。如果 md5() 以外的其他算法同样安全(或更安全)、相当快且理想情况下是单向的,我也愿意接受其他算法。
The reason I'm searching for said function is for the same purpose I would use PHP's md5() function: to store a one-way hash of a user's password in a database rather than the actual text of the user's password (in case the database's data is ever compromised, the user's passwords would still be relatively secret).
我搜索上述函数的原因与我使用 PHP 的 md5() 函数的目的相同:将用户密码的单向哈希存储在数据库中,而不是用户密码的实际文本(以防万一数据库的数据曾经被泄露,用户的密码仍然相对保密)。
I've spent around two hours searching now. All the code I've found either was for getting an MD5 of file data (instead of just a string), wouldn't compile, was for another programming language, or required an entire library (such as Crypto++, OpenSSL, hashlib++) to be added to my project, some of which are very large (is that really necessary when all I want is just one one-way string hashing function?).
我现在花了大约两个小时搜索。我发现的所有代码要么用于获取文件数据的 MD5(而不仅仅是字符串),要么无法编译,要么用于另一种编程语言,要么需要整个库(例如 Crypto++、OpenSSL、hashlib++)才能添加到我的项目中,其中一些非常大(当我想要的只是一个单向字符串散列函数时,这真的有必要吗?)。
Seeing as how this is a common need, I'm assuming someone has already written and made available exactly what I'm looking for.. can someone point me to it?
看到这是一个常见的需求,我假设有人已经编写并提供了我正在寻找的内容..有人可以指点我吗?
Thanks in advance.
提前致谢。
回答by Adam Rosenfield
Seriously, use a library (OpenSSL is a good choice). They're well-tested, and you can just drop them into your project without having to worry if you get the code right or not. Don't worry about the size of the library, any functions you don't use will not be included in your final executable.
说真的,使用一个库(OpenSSL 是一个不错的选择)。它们已经过充分测试,您可以将它们放入您的项目中,而不必担心代码是否正确。不要担心库的大小,您不使用的任何函数都不会包含在您的最终可执行文件中。
I'd also recommend avoiding MD5, as it has known weaknesses, in favor of something stronger such as SHA-256 or Blowfish.
我还建议避免使用 MD5,因为它有已知的弱点,而支持更强大的东西,例如 SHA-256 或 Blowfish。
But whichever algorithm and implementation you go with, do not forget to salt your inputs!
但是无论您使用哪种算法和实现,都不要忘记为您的输入加盐!
回答by B. Nadolson
Wikipedia's MD5 simple implementation has easy code and is very fast.
维基百科的 MD5 简单实现代码简单,速度非常快。
I would recommend it over the above solutions (for MD5 if it must be MD5) because it does not require an external library and the code does not contain #ifdefs
我会推荐它超过上述解决方案(对于 MD5,如果它必须是 MD5),因为它不需要外部库并且代码不包含 #ifdefs
/*
* Simple MD5 implementation
*
* Compile with: gcc -o md5 -O3 -lm md5.c
*
* NOTE: this code only works on little-endian machines.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
// Constants are the integer part of the sines of integers (in radians) * 2^32.
const uint32_t k[64] = {
0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee ,
0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501 ,
0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be ,
0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821 ,
0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa ,
0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8 ,
0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed ,
0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a ,
0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c ,
0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70 ,
0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05 ,
0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665 ,
0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039 ,
0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1 ,
0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1 ,
0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 };
// leftrotate function definition
#define LEFTROTATE(x, c) (((x) << (c)) | ((x) >> (32 - (c))))
// These vars will contain the hash
uint32_t h0, h1, h2, h3;
void md5(uint8_t *initial_msg, size_t initial_len) {
// Message (to prepare)
uint8_t *msg = NULL;
int new_len;
uint32_t bits_len;
int offset;
uint32_t *w;
uint32_t a, b, c, d, i, f, g, temp;
// Note: All variables are unsigned 32 bit and wrap modulo 2^32 when calculating
// r specifies the per-round shift amounts
const uint32_t r[] = {7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,
5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20,
4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,
6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21};
// Initialize variables - simple count in nibbles:
h0 = 0x67452301;
h1 = 0xefcdab89;
h2 = 0x98badcfe;
h3 = 0x10325476;
// Pre-processing: adding a single 1 bit
//append "1" bit to message
/* Notice: the input bytes are considered as bits strings,
where the first bit is the most significant bit of the byte.[37] */
// Pre-processing: padding with zeros
//append "0" bit until message length in bit ≡ 448 (mod 512)
//append length mod (2 pow 64) to message
for(new_len = initial_len*8 + 1; new_len%512!=448; new_len++);
new_len /= 8;
msg = (uint8_t*)calloc(new_len + 64, 1); // also appends "0" bits
// (we alloc also 64 extra bytes...)
memcpy(msg, initial_msg, initial_len);
msg[initial_len] = 128; // write the "1" bit
bits_len = 8*initial_len; // note, we append the len
memcpy(msg + new_len, &bits_len, 4); // in bits at the end of the buffer
// Process the message in successive 512-bit chunks:
//for each 512-bit chunk of message:
for(offset=0; offset<new_len; offset += (512/8)) {
// break chunk into sixteen 32-bit words w[j], 0 ≤ j ≤ 15
w = (uint32_t *) (msg + offset);
#ifdef DEBUG
printf("offset: %d %x\n", offset, offset);
int j;
for(j =0; j < 64; j++) printf("%x ", ((uint8_t *) w)[j]);
puts("");
#endif
// Initialize hash value for this chunk:
a = h0;
b = h1;
c = h2;
d = h3;
// Main loop:
for(i = 0; i<64; i++) {
if (i < 16) {
f = (b & c) | ((~b) & d);
g = i;
} else if (i < 32) {
f = (d & b) | ((~d) & c);
g = (5*i + 1) % 16;
} else if (i < 48) {
f = b ^ c ^ d;
g = (3*i + 5) % 16;
} else {
f = c ^ (b | (~d));
g = (7*i) % 16;
}
temp = d;
d = c;
c = b;
b = b + LEFTROTATE((a + f + k[i] + w[g]), r[i]);
a = temp;
}
// Add this chunk's hash to result so far:
h0 += a;
h1 += b;
h2 += c;
h3 += d;
}
// cleanup
free(msg);
}
int main(int argc, char **argv) {
if (argc < 2) {
printf("usage: %s 'string'\n", argv[0]);
return 1;
}
char *msg = argv[1];
size_t len = strlen(msg);
// benchmark
int i;
for (i = 0; i < 1000000; i++) {
md5((uint8_t*)msg, len);
}
//var char digest[16] := h0 append h1 append h2 append h3 //(Output is in little-endian)
uint8_t *p;
// display result
p=(uint8_t *)&h0;
printf("%2.2x%2.2x%2.2x%2.2x", p[0], p[1], p[2], p[3], h0);
p=(uint8_t *)&h1;
printf("%2.2x%2.2x%2.2x%2.2x", p[0], p[1], p[2], p[3], h1);
p=(uint8_t *)&h2;
printf("%2.2x%2.2x%2.2x%2.2x", p[0], p[1], p[2], p[3], h2);
p=(uint8_t *)&h3;
printf("%2.2x%2.2x%2.2x%2.2x", p[0], p[1], p[2], p[3], h3);
puts("");
return 0;
}
回答by Joshua
SHA-1 is easy. Pseudocode here: http://en.wikipedia.org/wiki/SHA-1
SHA-1 很容易。这里的伪代码:http: //en.wikipedia.org/wiki/SHA-1
HOWEVER, you need to salt your passwords. This means you save a few bytes of random data in front of the password and hashed password.
但是,您需要为密码加盐。这意味着您在密码和散列密码前面保存了几个字节的随机数据。
General form (salt is fixed length): salt + sha1(salt + password) = hash
一般形式(salt为定长):salt + sha1(salt + password) = hash
回答by Code Monkey
here is a site that has the MD5 algorithm in many languages: http://userpages.umbc.edu/~mabzug1/cs/md5/md5.html
这是一个拥有多种语言的 MD5 算法的站点:http: //userpages.umbc.edu/~mabzug1/cs/md5/md5.html
also if you use Visual C++, you can use .NET which has encryption support here is some documentation:
此外,如果您使用 Visual C++,则可以使用具有加密支持的 .NET,这里有一些文档:
http://msdn.microsoft.com/en-us/library/system.security.cryptography.md5.aspx#Y0
http://msdn.microsoft.com/en-us/library/system.security.cryptography.md5.aspx#Y0
hope that helps!
希望有帮助!