md5加密算法的C(C++)代码实现(完整)

合集下载

常用加密算法MD5、SHA-2和AES源码分享(CC++)

常用加密算法MD5、SHA-2和AES源码分享(CC++)

常⽤加密算法MD5、SHA-2和AES源码分享(CC++) 最近了解了⼀些加密算法,学习整理⼀些⽬前⽐较常⽤的三种加密⽅式(散列、对称、⾮对称)的相关经典算法(MD5、SHA-2、AES、RSA),这次分享的是MD5、SHA-2和ASE的纯C源码,另外两个我找时间整理好后会在贴出来。

⼤概介绍下这三种算法,详细的相关内容可以在⽹上搜索。

MD5是⼀种散列算法可以将任何数据散列成128位,速度很快,⼀般感觉⽤于数据⽂件校验⽐较多(安全性相对较低⽽且散列位数128位还是有概率碰撞,虽然极低极低,所以也有了另外这个SHA-2散列算法)。

AES是⼀种⾮常安全的对称加密,数据传输加密都可以⽤,然后有128、192、256位密钥,当然密钥越长加密解密越慢,看情况使⽤。

三种算法的核⼼算法代码都是我在⽹上查找的: MD5是基于Ron Rivest(RSA的那个R..)的算法,实现是由Colin Plumb 在1993年实现的。

AES核⼼算法源码() SHA2核⼼算法源码() 我对其进⾏了整理和封装,最⼤程度⽅便使⽤ MD5因为不牵扯密钥和解密所以超简单,两个接⼝⼀个散列⽂件⼀个散列数据: void MD5File(const char *filename, unsigned char *digest); void MD5Data(const unsigned char *data, unsigned int len, unsigned char *digest); AES⾸先得确认密钥长度,我这个是256位测试的,我代码⾥已经定义好相关三个宏AES_128、AES_192、AES_256,⾃⾏替换代⼊,接⼝我分别封装了加密解密数据和⽂件⼀共四个接⼝: int aes_cipher_data(uint8_t *in, size_t in_len, uint8_t *out, uint8_t *key, size_t key_len); int aes_decipher_data(uint8_t *in, size_t in_len, uint8_t *out, size_t *out_len, uint8_t *key, size_t key_len); int aes_cipher_file(const char *in_filename, const char *out_filename, uint8_t *key, size_t key_len); int aes_decipher_file(const char *in_filename, const char *out_filename, uint8_t *key, size_t key_len); 因为aes加密需要进⾏补位之前没有做,我这次更新添加了PKCS5Padding补位⽅法,填充的原则是:数据长度除16,余数不为16,需要补满16个字节,填充(16-len)个(16-len),等于0额外填充16个16。

c语言md5加密函数

c语言md5加密函数

c语言md5加密函数摘要:1.引言2.MD5 加密算法简介3.C 语言实现MD5 加密函数4.示例代码及运行结果5.总结正文:1.引言随着信息技术的不断发展,数据安全已成为越来越受到关注的问题。

在众多的加密算法中,MD5 算法是一种广泛应用的摘要算法,它能够将任意长度的输入数据转化为固定长度的输出,通常为128 位二进制数。

在C 语言中,如何实现MD5 加密函数呢?本文将详细介绍C 语言中MD5 加密函数的实现方法。

2.MD5 加密算法简介MD5(Message-Digest 5)算法是一种基于Hash 函数的摘要算法,由美国计算机科学家Ronald Rivest 于1991 年提出。

它的主要作用是将不同长度的输入数据转化为固定长度的输出,即128 位二进制数。

MD5 算法的输入数据可以是任意长度,但输出总是128 位。

由于其算法复杂度高、碰撞抵抗能力强等特点,MD5 算法被广泛应用于数据完整性校验、数字签名等领域。

3.C 语言实现MD5 加密函数下面我们将给出一个C 语言实现的MD5 加密函数示例。

这个示例代码是基于OpenSSL 库的,因此在使用前需要先安装OpenSSL 库。

以下是代码实现:```c#include <stdio.h>#include <string.h>#include <openssl/md5.h>// 计算MD5 加密void md5_encrypt(const char *input, char *output) {MD5_CTX md5;MD5_Init(&md5);MD5_Update(&md5, input, strlen(input));MD5_Final(output, &md5);}int main() {char input[] = "Hello, world!";char output[MD5_DIGEST_LENGTH];printf("原始数据:%s", input);md5_encrypt(input, output);printf("MD5 加密后的数据:");for (int i = 0; i < MD5_DIGEST_LENGTH; i++) {printf("%02x", output[i]);}printf("");return 0;}```这段代码首先引入了必要的头文件,然后定义了一个名为`md5_encrypt`的函数,用于计算输入字符串的MD5 加密。

c# 实现MD5,SHA1,SHA256,SHA512等常用加密算法

c# 实现MD5,SHA1,SHA256,SHA512等常用加密算法
ICryptoTransform ct;
MemoryStream ms;
CryptoStream cs;
byte[] byt;
sa = new DESCryptoServiceProvider();
/// </summary>
/// <param name="IsCaseSensitive">是否区分大小写</param>
/// <param name="IsReturnNum">是否返回为加密后字符的Byte代码</param>
public HashEncrypt(bool IsCaseSensitive, bool IsReturnNum)
key += "12345678";
IV += "12345678";
key = key.Substring(0, 8);
IV = IV.Substring(0, 8);
SymmetricAlgorithm sa;
******************/
namespace 档案数字化加工
{
/**//// <summary>
/// 类名:HashEncrypt
/// 作用:对传入的字符串进行Hash运算,返回通过Hash算法加密过的字串。
/// 属性:[无]
/// 构造函数额参数:
ICryptoTransform ct;
MemoryStream ms;
CryptoStream cs;
byte[] byt;

C#中算法

C#中算法

C#使用MD5算法对密码进行加密对密码进行加密的算法有很多种,在C#中较常使用的是MD5加密算法。

它是一种用于产生数字签名的单项散列算法,具体代码如下:public string Encrypt(string strPwd){MD5 md5 = new MD5CryptoServiceProvider();byte[] data = System.Text.Encoding.Default.GetBytes(strPwd);//将字符编码为一个字节序列byte[] md5data = puteHash(data);//计算data字节数组的哈希值md5.Clear();string str = "";for (int i = 0; i <md5data.Length-1; i++){str += md5data[i].ToString("x").PadLeft(2,'0');}return str;}注意:在编码之前应先引入命名空间System.Security.Cryptography。

而且始用散列算法对原始密码加密后无法再恢复。

这也是MD5加密算法的一个蔽端。

C#实现二、八、十六进制数转十进制数的算法二进制换为十进制的方法,例如:二进制数:11001十进制数:1*24+1*23+0*22+0*21+1*20=25八进制换为十进制的方法,例如:八进制数:32007十进制数:3*84+2*83+0*82+0*81+7*80=13319十六进制换为十进制的方法,例如:十六进制数:a20f(由于十六进制数用a~f表示10~15之间的数,所以计算时将a~f用10~15表示)十进制数:10*83+2*82+0*81+15*80=41487通过以上二、八、十六进制数转十进制数的计算方法,可得出计算的代码为://参数Num为需要转换的数,n为该数的进制public string ToD(string Num, int n){char[] nums=Num.ToCharArray ();int d = 0;for (int i = 0; i <nums.Length ; i++){string number=nums [i].ToString ();if (n == 16){switch (number.ToUpper ()){case "A":number = "10";break;case "B":number = "11";break;case "C":number = "12";break;case "D":number = "13";break;case "E":number = "14";break;case "F":number = "15";break;}}Double power = Math.Pow(Convert.ToDouble (n),Convert.ToDouble ( nums.Length - (i +1)));d = d + Convert.ToInt32 (number) * Convert.ToInt32 (power);}return d.ToString ();}C#十进制数转十六进制数的算法十进数转换为十六进制数的方法与以上两种的转换方法相似,不同之处除了除数改为16外,还需要将余数为10~15的数改为A~F的形式。

加密系列MD5加密和解密算法详解代码示例

加密系列MD5加密和解密算法详解代码示例

加密系列MD5加密和解密算法详解代码示例MD5加密算法是一种广泛应用的密码加密算法,它将任意长度的数据映射为固定长度的128位哈希值。

MD5加密算法是不可逆的,即通过密文无法还原得到原始数据。

MD5加密算法的实现可以通过编写代码来完成。

下面是一个示例的MD5加密算法的代码:```import hashlibdef md5_encrypt(data):md5 = hashlib.md5md5.update(data.encode('utf-8'))return md5.hexdigestif __name__ == '__main__':data = input("请输入需要加密的数据:")encrypted_data = md5_encrypt(data)print("加密结果为:", encrypted_data)```以上代码实现了一个简单的MD5加密算法。

首先导入了`hashlib`模块,该模块提供了一系列用于数据加密的算法,包括MD5算法。

`md5_encrypt`函数接收一个字符串作为输入数据,并将其转换为字节流形式,然后使用`hashlib.md5`方法创建了一个MD5对象。

接着,通过调用MD5对象的`update`方法将输入数据添加到加密流程中。

最后,通过调用MD5对象的`hexdigest`方法获得加密后的结果,并将其返回。

在`if __name__ == '__main__'`下方的代码段中,首先获取用户输入的数据,然后调用`md5_encrypt`函数对其进行加密,并将结果打印到控制台。

下面是MD5解密算法的示例代码:```import hashlibdef md5_decrypt(encrypted_data):md5 = hashlib.md5md5.update(encrypted_data.encode('utf-8'))return md5.hexdigestif __name__ == '__main__':encrypted_data = input("请输入需要解密的数据:")decrypted_data = md5_decrypt(encrypted_data)print("解密结果为:", decrypted_data)```以上代码实现了一个简单的MD5解密算法。

MD5算法原理及代码实现

MD5算法原理及代码实现

MD5算法原理及代码实现MD5(Message Digest Algorithm 5)是一种被广泛使用的消息摘要算法,它是MD家族中的第五个版本。

MD5算法能将任意长度的输入数据转换为一个128位(16字节)的散列值,通常表示为32个十六进制数。

1. 填充(Padding):为了使输入消息的位数对512求余数等于448,填充是必要的。

例如,如果输入消息的位数是L,填充后的消息长度为K* 512 + 448,其中K是一个非负整数。

填充后的消息被分为512位(64字节)的块。

2. 初始化(Initialization):算法对四个32位的缓冲区A、B、C、D进行初始化,通常初始化为常量。

这些缓冲区用于保存中间计算结果。

3. 循环(Iteration):通过进行四轮循环的操作,将每个512位的块以及前一个块的连续散列结果作为输入,产生新的散列结果。

每轮循环包括四个步骤:数据的复制、数据的变换、数据的交换以及数据的加法。

4. 输出(Output):将最后一轮循环的输出结果根据顺序连接起来,形成128位的散列值。

下面是一个简单的MD5算法的代码示例,使用Python语言实现:```pythonimport hashlibdef md5(message):md5_hash = hashlib.md5md5_hash.update(message.encode('utf-8'))return md5_hash.hexdigest#测试message = "Hello, world!"md5_value = md5(message)print("MD5 hash value:", md5_value)```在上述代码中,我们首先导入了Python标准库中的hashlib模块,该模块提供了MD5算法的实现。

然后,我们定义了一个名为md5的函数,它接受一个字符串形式的消息作为输入,并返回该消息的MD5散列值。

MD5算法在MFC下实现

MD5算法在MFC下实现

MD5算法在MFC下实现在MFC(Microsoft Foundation Classes)下实现MD5算法,可以按照以下步骤进行:1. 首先,需要引入头文件 "afx.h" 和 "wincrypt.h"。

afx.h 包含了 MFC 的核心功能,而 wincrypt.h 则包含了使用 Windows 加密 API 的相关定义和函数。

```cpp#include "afx.h"#include "wincrypt.h"```2. 为了使用 MD5 算法,我们需要定义一个函数 `CalculateMD5`,该函数接受一个字符串作为输入,并返回该字符串的 MD5 哈希值。

```cppCString CalculateMD5(const CString& input)//初始化MD5并获取上下文句柄HCRYPTPROV hProv = NULL;HCRYPTHASH hHash = NULL;if(!CryptAcquireContextW(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))//处理错误//...}if(!CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash)) //处理错误CryptReleaseContext(hProv, 0);//...}//更新哈希值if(!CryptHashData(hHash, (BYTE*)(LPCTSTR)input, input.GetLength( * sizeof(TCHAR), 0))//处理错误CryptDestroyHash(hHash);CryptReleaseContext(hProv, 0);//...}//计算哈希值BYTE hash[16];DWORD cbHash = sizeof(hash);CString md5Hash;if(CryptGetHashParam(hHash, HP_HASHVAL, hash, &cbHash, 0)) //将二进制哈希值转换为字符串形式for(DWORD i = 0; i < cbHash; i++)CString byte;byte.Format(_T("%02x"), hash[i]);md5Hash += byte;}}//释放资源CryptDestroyHash(hHash);CryptReleaseContext(hProv, 0);return md5Hash;```3. 在需要使用 MD5 算法的位置,调用 `CalculateMD5` 函数即可计算字符串的 MD5 哈希值。

C语言实现MD5算法

C语言实现MD5算法

C语言实现MD5算法MD5(Message-Digest Algorithm 5)是一种常用的哈希函数算法,广泛用于验证数据完整性、密码存储和数字证书等领域。

下面是使用C语言实现MD5算法的代码。

这段代码包含了MD5算法的各个步骤,包括初始化MD5结构体、填充数据、更新状态、计算摘要等。

```c#include <stdio.h>#include <stdint.h>#include <string.h>//定义MD5常量#define B 0xEFCDAB89#define C 0x98BADCFE//循环左移宏定义#define LEFT_ROTATE(x, n) (((x) << (n)) , ((x) >> (32-(n)))) //填充消息void padMessage(uint8_t *message, uint32_t length)//计算需要填充的字节数uint32_t padLength = (length % sizeof(uint32_t) == 56) ? 64 : 56;padLength = padLength - (length % sizeof(uint32_t));//填充1位1message[length++] = 0x80;//填充0位for (uint32_t i = 0; i < padLength; i++) message[length++] = 0x00;}//在消息末尾添加原始消息的长度(以位表示)for (uint32_t i = 0; i < sizeof(uint32_t); i++) message[length++] = (length << 3) >> (i * 8); }//初始化MD5结构体void initMD5(uint32_t *state)state[0] = A;state[1] = B;state[2] = C;state[3] = D;//更新状态void updateState(uint32_t *state, uint32_t *M)uint32_t A = state[0], B = state[1], C = state[2], D = state[3];//定义MD5循环运算函数#define MD5_FUNCTION(a, b, c, d, k, s, i) \a=b+LEFT_ROTATE((a+F(b,c,d)+M[k]+T[i]),s)//迭代压缩消息MD5_FUNCTION(A,B,C,D,0,7,1);MD5_FUNCTION(D,A,B,C,1,12,2);MD5_FUNCTION(C,D,A,B,2,17,3);MD5_FUNCTION(B,C,D,A,3,22,4);MD5_FUNCTION(A,B,C,D,4,7,5);MD5_FUNCTION(D,A,B,C,5,12,6);MD5_FUNCTION(C,D,A,B,6,17,7);MD5_FUNCTION(B,C,D,A,7,22,8);MD5_FUNCTION(A,B,C,D,8,7,9);MD5_FUNCTION(D,A,B,C,9,12,10);MD5_FUNCTION(C,D,A,B,10,17,11);MD5_FUNCTION(B,C,D,A,11,22,12);MD5_FUNCTION(A,B,C,D,12,7,13);MD5_FUNCTION(C,D,A,B,14,17,15); MD5_FUNCTION(B,C,D,A,15,22,16); MD5_FUNCTION(A,B,C,D,1,5,17); MD5_FUNCTION(D,A,B,C,6,9,18); MD5_FUNCTION(C,D,A,B,11,14,19); MD5_FUNCTION(B,C,D,A,0,20,20); MD5_FUNCTION(A,B,C,D,5,5,21); MD5_FUNCTION(D,A,B,C,10,9,22); MD5_FUNCTION(C,D,A,B,15,14,23); MD5_FUNCTION(B,C,D,A,4,20,24); MD5_FUNCTION(A,B,C,D,9,5,25); MD5_FUNCTION(D,A,B,C,14,9,26); MD5_FUNCTION(C,D,A,B,3,14,27); MD5_FUNCTION(B,C,D,A,8,20,28); MD5_FUNCTION(A,B,C,D,13,5,29); MD5_FUNCTION(D,A,B,C,2,9,30); MD5_FUNCTION(C,D,A,B,7,14,31); MD5_FUNCTION(B,C,D,A,12,20,32);MD5_FUNCTION(D,A,B,C,8,11,34); MD5_FUNCTION(C,D,A,B,11,16,35); MD5_FUNCTION(B,C,D,A,14,23,36); MD5_FUNCTION(A,B,C,D,1,4,37); MD5_FUNCTION(D,A,B,C,4,11,38); MD5_FUNCTION(C,D,A,B,7,16,39); MD5_FUNCTION(B,C,D,A,10,23,40); MD5_FUNCTION(A,B,C,D,13,4,41); MD5_FUNCTION(D,A,B,C,0,11,42); MD5_FUNCTION(C,D,A,B,3,16,43); MD5_FUNCTION(B,C,D,A,6,23,44); MD5_FUNCTION(A,B,C,D,9,4,45); MD5_FUNCTION(D,A,B,C,12,11,46); MD5_FUNCTION(C,D,A,B,15,16,47); MD5_FUNCTION(B,C,D,A,2,23,48); MD5_FUNCTION(A,B,C,D,0,6,49); MD5_FUNCTION(D,A,B,C,7,10,50); MD5_FUNCTION(C,D,A,B,14,15,51);MD5_FUNCTION(A,B,C,D,12,6,53); MD5_FUNCTION(D,A,B,C,3,10,54); MD5_FUNCTION(C,D,A,B,10,15,55); MD5_FUNCTION(B,C,D,A,1,21,56); MD5_FUNCTION(A,B,C,D,8,6,57); MD5_FUNCTION(D,A,B,C,15,10,58); MD5_FUNCTION(C,D,A,B,6,15,59); MD5_FUNCTION(B,C,D,A,13,21,60); MD5_FUNCTION(A,B,C,D,4,6,61); MD5_FUNCTION(D,A,B,C,11,10,62); MD5_FUNCTION(C,D,A,B,2,15,63); MD5_FUNCTION(B,C,D,A,9,21,64); #undef MD5_FUNCTION//更新状态state[0] += A;state[1] += B;state[2] += C;state[3] += D;//计算MD5摘要void md5(uint8_t *message, uint32_t length, uint32_t *digest) //初始化MD5结构体uint32_t state[4];initMD5(state);//填充消息padMessage(message, length);//计算消息分组数量uint32_t numOfBlocks = length / 64;//处理每个分组for (uint32_t i = 0; i < numOfBlocks; i++)uint32_t M[16];memcpy(M, message + (i * 64), 64);//更新状态updateState(state, M);}//获取MD5摘要memcpy(digest, state, 16);int mai//测试用例uint8_t message[] = "Hello, MD5!";uint32_t length = sizeof(message) - 1;//计算MD5摘要uint32_t digest[4];md5(message, length, digest);//输出摘要printf("MD5 Digest: ");for (int i = 0; i < 4; i++)printf("%02x", ((uint8_t*)digest)[i]);}printf("\n");return 0;```以上是使用C语言实现MD5算法的代码。

MD5加密算法原理及实现

MD5加密算法原理及实现

MD5加密算法原理及实现MD5消息摘要算法,属Hash算法⼀类。

MD5算法对输⼊任意长度的消息进⾏运⾏,产⽣⼀个128位的消息摘要。

以下所描述的消息长度、填充数据都以位(Bit)为单位,字节序为⼩端字节。

算法原理1、数据填充对消息进⾏数据填充,使消息的长度对512取模得448,设消息长度为X,即满⾜X mod 512=448。

根据此公式得出需要填充的数据长度。

填充⽅法:在消息后⾯进⾏填充,填充第⼀位为1,其余为0。

2、添加消息长度在第⼀步结果之后再填充上原消息的长度,可⽤来进⾏的存储长度为64位。

如果消息长度⼤于264,则只使⽤其低64位的值,即(消息长度对 264取模)。

在此步骤进⾏完毕后,最终消息长度就是512的整数倍。

3、数据处理准备需要⽤到的数据:4个常数:A = 0x67452301, B = 0x0EFCDAB89, C = 0x98BADCFE, D = 0x10325476;4个函数:F(X,Y,Z)=(X & Y) | ((~X) & Z); G(X,Y,Z)=(X & Z) | (Y & (~Z)); H(X,Y,Z)=X ^ Y ^ Z; I(X,Y,Z)=Y ^ (X | (~Z));把消息分以512位为⼀分组进⾏处理,每⼀个分组进⾏4轮变换,以上⾯所说4个常数为起始变量进⾏计算,重新输出4个变量,以这4个变量再进⾏下⼀分组的运算,如果已经是最后⼀个分组,则这4个变量为最后的结果,即MD5值。

具体计算的实现较为复杂,建议查阅相关书籍,下⾯给出在C++上的实现代码。

代码实现#MD5.h1 #ifndef MD5H2#define MD5H3 #include <math.h>4 #include <Windows.h>56void ROL(unsigned int &s, unsigned short cx); //32位数循环左移实现函数7void ltob(unsigned int &i); //B\L互转,接受UINT类型8 unsigned int* MD5(const char* mStr); //接⼝函数,并执⾏数据填充,计算MD5时调⽤此函数910#endif#MD5.cpp1 #include "MD5.h"23/*4组计算函数*/4 inline unsigned int F(unsigned int X, unsigned int Y, unsigned int Z)5 {6return (X & Y) | ((~X) & Z);7 }8 inline unsigned int G(unsigned int X, unsigned int Y, unsigned int Z)9 {10return (X & Z) | (Y & (~Z));11 }12 inline unsigned int H(unsigned int X, unsigned int Y, unsigned int Z)13 {14return X ^ Y ^ Z;15 }16 inline unsigned int I(unsigned int X, unsigned int Y, unsigned int Z)17 {18return Y ^ (X | (~Z));19 }20/*4组计算函数结束*/2122/*32位数循环左移实现函数*/23void ROL(unsigned int &s, unsigned short cx)24 {25if (cx > 32)cx %= 32;26 s = (s << cx) | (s >> (32 - cx));27return;28 }2930/*B\L互转,接收UINT类型*/31void ltob(unsigned int &i)32 {33 unsigned int tmp = i;//保存副本34byte *psour = (byte*)&tmp, *pdes = (byte*)&i;35 pdes += 3;//调整指针,准备左右调转36for (short i = 3; i >= 0; --i)37 {38 CopyMemory(pdes - i, psour + i, 1);39 }40return;41 }4243/*44MD5循环计算函数,label=第⼏轮循环(1<=label<=4),lGroup数组=4个种⼦副本,M=数据(16组32位数指针)45种⼦数组排列⽅式: --A--D--C--B--,即 lGroup[0]=A; lGroup[1]=D; lGroup[2]=C; lGroup[3]=B;46*/47void AccLoop(unsigned short label, unsigned int *lGroup, void *M)48 {49 unsigned int *i1, *i2, *i3, *i4, TAcc, tmpi = 0; //定义:4个指针; T表累加器;局部变量50 typedef unsigned int(*clac)(unsigned int X, unsigned int Y, unsigned int Z); //定义函数类型51const unsigned int rolarray[4][4] = {52 { 7, 12, 17, 22 },53 { 5, 9, 14, 20 },54 { 4, 11, 16, 23 },55 { 6, 10, 15, 21 }56 };//循环左移-位数表57const unsigned short mN[4][16] = {58 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },59 { 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12 },60 { 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2 },61 { 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 }62 };//数据坐标表63const unsigned int *pM = static_cast<unsigned int*>(M);//转换类型为32位的Uint64 TAcc = ((label - 1) * 16) + 1; //根据第⼏轮循环初始化T表累加器65 clac clacArr[4] = { F, G, H, I }; //定义并初始化计算函数指针数组6667/*⼀轮循环开始(16组->16次)*/68for (short i = 0; i < 16; ++i)69 {70/*进⾏指针⾃变换*/71 i1 = lGroup + ((0 + i) % 4);72 i2 = lGroup + ((3 + i) % 4);73 i3 = lGroup + ((2 + i) % 4);74 i4 = lGroup + ((1 + i) % 4);7576/*第⼀步计算开始: A+F(B,C,D)+M[i]+T[i+1] 注:第⼀步中直接计算T表*/77 tmpi = (*i1 + clacArr[label - 1](*i2, *i3, *i4) + pM[(mN[label - 1][i])] + (unsigned int)(0x100000000UL * abs(sin((double)(TAcc + i)))));78 ROL(tmpi, rolarray[label - 1][i % 4]);//第⼆步:循环左移79 *i1 = *i2 + tmpi;//第三步:相加并赋值到种⼦80 }81return;82 }8384/*接⼝函数,并执⾏数据填充*/85 unsigned int* MD5(const char* mStr)86 {87 unsigned int mLen = strlen(mStr); //计算字符串长度88if (mLen < 0) return0;89 unsigned int FillSize = 448 - ((mLen * 8) % 512); //计算需填充的bit数90 unsigned int FSbyte = FillSize / 8; //以字节表⽰的填充数91 unsigned int BuffLen = mLen + 8 + FSbyte; //缓冲区长度或者说填充后的长度92 unsigned char *md5Buff = new unsigned char[BuffLen]; //分配缓冲区93 CopyMemory(md5Buff, mStr, mLen); //复制字符串到缓冲区9495/*数据填充开始*/96 md5Buff[mLen] = 0x80; //第⼀个bit填充197 ZeroMemory(&md5Buff[mLen + 1], FSbyte - 1); //其它bit填充0,另⼀可⽤函数为FillMemory98 unsigned long long lenBit = mLen * 8ULL; //计算字符串长度,准备填充99 CopyMemory(&md5Buff[mLen + FSbyte], &lenBit, 8); //填充长度100/*数据填充结束*/101102/*运算开始*/103 unsigned int LoopNumber = BuffLen / 64; //以16个字为⼀分组,计算分组数量104 unsigned int A = 0x67452301, B = 0x0EFCDAB89, C = 0x98BADCFE, D = 0x10325476;//初始4个种⼦,⼩端类型105 unsigned int *lGroup = new unsigned int[4]{ A, D, C, B}; //种⼦副本数组,并作为返回值返回106for (unsigned int Bcount = 0; Bcount < LoopNumber; ++Bcount) //分组⼤循环开始107 {108/*进⼊4次计算的⼩循环*/109for (unsigned short Lcount = 0; Lcount < 4;)110 {111 AccLoop(++Lcount, lGroup, &md5Buff[Bcount * 64]);112 }113/*数据相加作为下⼀轮的种⼦或者最终输出*/114 A = (lGroup[0] += A);115 B = (lGroup[3] += B);116 C = (lGroup[2] += C);117 D = (lGroup[1] += D);118 }119/*转换内存中的布局后才能正常显⽰*/120 ltob(lGroup[0]);121 ltob(lGroup[1]);122 ltob(lGroup[2]);123 ltob(lGroup[3]);124 delete[] md5Buff; //清除内存并返回125return lGroup;126 }再给出调⽤实例(以win32控制台应⽤程序为例):#main.cpp1 #include <iostream>2 #include <string.h>3 #include <stdlib.h>4 #include "MD5.h"56int main(int argc, char **argv)7 {8char tmpstr[256], buf[4][10];9 std::cout << "请输⼊要加密的字符串:";10 std::cin >> tmpstr;11 unsigned int* tmpGroup = MD5(tmpstr);12 sprintf_s(buf[0], "%8X", tmpGroup[0]);13 sprintf_s(buf[1], "%8X", tmpGroup[3]);14 sprintf_s(buf[2], "%8X", tmpGroup[2]);15 sprintf_s(buf[3], "%8X", tmpGroup[1]);16 std::cout <<"MD5:"<< buf[0] << buf[1] << buf[2] << buf[3] << std::endl; 1718 delete[] tmpGroup;19return0; //在此下断点才能看到输出的值20 }注:以上代码在VS2013上编译通过。

对主机的mac地址MD5加密

对主机的mac地址MD5加密

Java实现主机mac地址加密,使用MD5加密算法。

一、代码1. LOCALMAC类package com.tydic.encr;import .InetAddress;import workInterface;import .SocketException;import .UnknownHostException;public class LOCALMAC {private String localMac;private static LOCALMAC lm;private LOCALMAC(){try {InetAddress ia = InetAddress.getLocalHost();this.localMac = Ip2LocalMac(ia);} catch (SocketException e) {e.printStackTrace();} catch (UnknownHostException e) {e.printStackTrace();}}public static LOCALMAC getInstance(){if(lm == null){lm = new LOCALMAC();}return lm;}private static String Ip2LocalMac(InetAddress ia) throws SocketException {//获取网卡,获取地址byte[] mac =NetworkInterface.getByInetAddress(ia).getHardwareAddress();StringBuffer sb = new StringBuffer("");for(int i=0; i<mac.length; i++) {if(i!=0) {sb.append("-");}//字节转换为整数int temp = mac[i]&0xff;String str = Integer.toHexString(temp);if(str.length()==1) {sb.append("0"+str);}else {sb.append(str);}}return sb.toString().toUpperCase();}public String getLocalMac() {return localMac;}}2.Password类package com.tydic.encr;import java.security.MessageDigest;public class Password {private final static String[] hexDigits= { "0", "1", "2", "3", "4", "5","6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };// 十六进制下数字到字符的映射数组/** 把inputString加密 */public static String createPassword(String inputString) { return encodeByMD5(inputString);}/** 对字符串进行MD5编码 */private static String encodeByMD5(String originString) { if (originString != null) {try {// 创建具有指定算法名称的信息摘要MessageDigest md = MessageDigest.getInstance("MD5");// 使用指定的字节数组对摘要进行最后更新,然后完成摘要计算byte[] results = md.digest(originString.getBytes());// 将得到的字节数组变成字符串返回String resultString = byteArrayToHexString(results);return resultString.toUpperCase();} catch (Exception ex) {ex.printStackTrace();}}return null;}/*** 字节数组转为十六进制字符串** @param b* 字节数组* @return十六进制字符串*/private static String byteArrayToHexString(byte[] b) {StringBuffer resultSb = new StringBuffer();for (int i = 0; i < b.length; i++) {resultSb.append(byteToHexString(b[i]));}return resultSb.toString();}/*** 将一个字节转化成十六进制形式的字符串*/private static String byteToHexString(byte b) {int n = b;if (n < 0)n = 256 + n;int d1 = n / 16;int d2 = n % 16;return hexDigits[d1] + hexDigits[d2];}public static void main(String[] args) {String localmac = LOCALMAC.getInstance().getLocalMac();String password = Password.createPassword(localmac);System.out.println("本机mac地址:" + localmac);System.out.println("对本机mac地址用MD5摘要后的字符串:"+ password);}}二、结果。

数据完整性校验-MD5,CRC,HMAC

数据完整性校验-MD5,CRC,HMAC

数据完整性校验-MD5,CRC,HMACMD5MD5(RFC1321)是Rivest于1991年对MD4的改进版本。

它对输⼊仍以512位分组,其输出是4个32位字的级联,与MD4相同。

MD5⽐MD4来得复杂,并且速度较之要慢⼀点,但更安全,在抗分析和抗差分⽅⾯表现更好。

MD5是⼀种不可逆的加密算法,⽬前是最牢靠的加密算法之⼀,尚没有能够逆运算的程序被开发出来,它对应任何字符串都可以加密成⼀段唯⼀的固定长度的代码。

那么它有什么⽤呢?很简单,通过它可以判断原始值是否正确(是否被更改过)。

⼀般⽤于密码的加密。

⽽我们所提供的MD5校验码就是针对安装程序的唯⼀对应的⼀段代码。

你可以使⽤任何MD5运算器对下载的⽂件进⾏运算,运算出来的结果如果完全符合我们提供的MD5校验码,那么说明你下载的这个程序没有被中途修改过。

这个特征码有如下特性,⾸先它不可逆,例如我有⼀段秘密的⽂字如:”MySecretWords”,经算法变换后得到MD5码(b9944e9367d2e40dd1f0c4040d4daaf7),把这个码告诉其他⼈,他们根据这个MD5码是没有系统的⽅法可以知道你原来的⽂字是什么的。

其次,这个码具有⾼度的离散性,也就是说,原信息的⼀点点变化就会导致MD5的巨⼤变化,例如,”ABC”MD5(902fbdd2b1df0c4f70b4a5d23525e932)和”ABC”(多了⼀空格)MD5(12c774468f981a9487c30773d8093561)差别⾮常⼤,⽽且之间没有任何关系,也就是说产⽣的MD5码是不可预测的。

最后由于这个码有128位那么长,所以任意信息之间具有相同MD5码的可能性⾮常之低,通常被认为是不可能的。

所以⼀般认为MD5码可以唯⼀地代表原信息的特征,通常⽤于密码的加密存储,数字签名,⽂件完整性验证等。

查看某⽂件的md5值,dos命令⾏如下certutil -hashfile D:\your.txt MD5SHASHA1是由NISTNSA设计为同DSA⼀起使⽤的,它对长度⼩于264的输⼊,产⽣长度为160bit的散列值,因此抗穷举(brute-force)性更好。

c语言md5加密函数

c语言md5加密函数

c语言md5加密函数C语言MD5加密函数MD5(Message Digest Algorithm 5)是一种广泛使用的密码散列函数,常用于数据加密和数据完整性验证。

在C语言中,我们可以通过编写MD5加密函数来实现对数据的加密操作。

本文将介绍如何使用C语言编写一个简单的MD5加密函数,并详细解释其原理和步骤。

一、MD5加密原理MD5加密算法基于消息摘要算法,它将任意长度的消息作为输入,通过一系列复杂的数学运算,生成一个固定长度的密文。

MD5算法的核心思想是将输入的消息进行分块处理,并对每个分块进行位运算和逻辑运算,最终得到一个128位的摘要。

MD5算法具有以下特点:1. 不可逆性:无法从加密后的密文推导出原始消息。

2. 唯一性:不同的输入会产生不同的摘要。

3. 完整性:对于相同的输入,产生的摘要是稳定的。

二、MD5加密步骤MD5算法的加密过程包括以下几个步骤:1. 填充消息:将消息的位数填充为448的倍数,填充方式为在消息末尾添加一个1和若干个0。

2. 添加长度:将填充后的消息长度添加到消息末尾,以64位二进制数表示。

3. 初始化缓冲区:初始化四个32位的缓冲区A、B、C、D,用于存储最终的摘要。

4. 分块处理:将填充后的消息分为若干个512位的分组,对每个分组进行处理。

5. 迭代压缩:对每个分组进行64轮的迭代压缩操作,更新缓冲区的值。

6. 输出结果:最后将缓冲区的值按照小端序输出,得到128位的摘要。

三、C语言实现MD5加密函数以下是一个简单的C语言实现MD5加密函数的示例代码:#include <stdio.h>#include <string.h>#include <stdint.h>// 定义MD5加密函数void md5_encrypt(const uint8_t *message, uint32_t len, uint8_t *digest) {// 初始化缓冲区uint32_t A = 0x67452301;uint32_t B = 0xEFCDAB89;uint32_t C = 0x98BADCFE;uint32_t D = 0x10325476;// 填充消息// ...// 添加长度// ...// 分块处理// ...// 迭代压缩// ...// 输出结果// ...}int main() {// 测试示例uint8_t message[] = "Hello, MD5!";uint8_t digest[16] = {0};md5_encrypt(message, strlen(message), digest); // 输出结果for (int i = 0; i < 16; i++) {printf("%02x", digest[i]);}printf("\n");return 0;}四、总结通过上述的示例代码,我们可以看到使用C语言编写MD5加密函数并不复杂。

MD5的代码

MD5的代码

从网上找的内嵌汇编的MD5代码,,bcb6下面调试通过。

优点是速度很快,缺点是只能在Windows下使用。

最后面有现成的 for bcb 的两个函数。

*/#include <vcl.h>#include <stdio.h>////////////////////////////////////////////////////////////////////////////////typedef struct {DWORD state[4]; //encypted messageDWORD count[2]; //bits of plaintextunsigned char buffer[64];}MD5_CTX;////////////////////////////////////////////////////////////////////////////////#define S11 7#define S12 12#define S13 17#define S14 22#define S21 5#define S22 9#define S23 14#define S24 20#define S31 4#define S32 11#define S33 16#define S34 23#define S41 6#define S42 10#define S43 15#define S44 21#define a esi#define b edi#define c edx#define d ebx#define tmp1 eax#define tmp2 ecx#define x(i) [x+4*i]static unsigned char PADDING[64] ={0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};#define FF(a, b, c, d, x, s, ac) \__asm mov tmp1,b; \__asm and tmp1,c; \__asm mov tmp2,b; \__asm not tmp2; \__asm and tmp2,d; \__asm or tmp2,tmp1; \__asm lea a,[tmp2+a+ac]; \__asm add a,x; \__asm rol a,s; \__asm add a,b;#define GG(a, b, c, d, x, s, ac) \__asm mov tmp1,b; \__asm and tmp1,d; \__asm mov tmp2,d; \__asm not tmp2; \__asm and tmp2,c; \__asm or tmp2,tmp1; \__asm lea a,[tmp2+a+ac]; \__asm add a,x; \__asm rol a,s; \__asm add a,b;#define HH(a,b,c, d, x, s, ac) \__asm mov tmp2,b; \__asm xor tmp2,c; \__asm xor tmp2,d; \__asm lea a,[tmp2+a+ac]; \__asm add a,x; \__asm rol a,s; \__asm add a,b;#define II(a, b, c, d, x, s, ac) \__asm mov tmp2,d; \__asm not tmp2; \__asm or tmp2,b; \__asm xor tmp2,c; \__asm lea a,[tmp2+a+ac]; \__asm add a,x; \__asm rol a,s; \__asm add a,b;static void MD5Transform (DWORD state[4], unsigned char block[64]);static void MD5Init (MD5_CTX *context){context->count[0] = context->count[1] = 0;context->state[0] = 0x67452301;context->state[1] = 0xefcdab89;context->state[2] = 0x98badcfe;context->state[3] = 0x10325476;}static void MD5Update (MD5_CTX *context, unsigned char *input, unsigned int inputLen) {unsigned int i, index, partLen;index = (unsigned int)((context->count[0] >> 3) & 0x3F);if ((context->count[0] += ((DWORD)inputLen << 3)) < ((DWORD)inputLen << 3))context->count[1]++;context->count[1] += ((DWORD)inputLen >> 29);partLen = 64 - index;if (inputLen >= partLen){CopyMemory(&context->buffer[index],input, partLen);MD5Transform (context->state, context->buffer);for (i = partLen; i + 63 < inputLen; i += 64){;}index = 0;}elsei = 0;/* Buffer remaining input */CopyMemory(&context->buffer[index],&input[i],inputLen-i);}static void MD5Final (MD5_CTX *context,unsigned char res[/*16*/]) {unsigned char *p=NULL;unsigned char bits[8];unsigned int i,index, padLen;CopyMemory(bits,context->count,8);index = (unsigned int)((context->count[0] >> 3) & 0x3f);padLen = (index < 56) ? (56 - index) : (120 - index);MD5Update (context, PADDING, padLen);MD5Update (context, bits, 8);p=(unsigned char*)(&(context->state[0]));for(i=0; i<16 ;i++)res[i]=*(p+i);}static void MD5Transform (DWORD state[4], unsigned char block[64]) {DWORD x[16];__asm{//initialmov a,0x67452301mov b,0xefcdab89mov c,0x98badcfemov d,0x10325476//copy string from block to state//考虑到用API会影响寄存器,所以自己实现这一段内存拷贝push esipush edixor ecx,ecxmov esi,dword ptr [block]lea edi,[x]ROLL:mov eax,dword ptr [esi+ecx]mov dword ptr [edi+ecx],eaxadd ecx,4cmp ecx,64jb ROLLpop edipop esi}/* Round 1 */FF(a, b, c, d, x( 0), S11, 0xd76aa478); /* 1 */FF(d, a, b, c, x( 1), S12, 0xe8c7b756); /* 2 */FF(c, d, a, b, x( 2), S13, 0x242070db); /* 3 */FF(b, c, d, a, x( 3), S14, 0xc1bdceee); /* 4 */FF(a, b, c, d, x( 4), S11, 0xf57c0faf); /* 5 */FF(d, a, b, c, x( 5), S12, 0x4787c62a); /* 6 */FF(c, d, a, b, x( 6), S13, 0xa8304613); /* 7 */FF(b, c, d, a, x( 7), S14, 0xfd469501); /* 8 */FF(a, b, c, d, x( 8), S11, 0x698098d8); /* 9 */FF(d, a, b, c, x( 9), S12, 0x8b44f7af); /* 10 */ FF(c, d, a, b, x(10), S13, 0xffff5bb1); /* 11 */FF(b, c, d, a, x(11), S14, 0x895cd7be); /* 12 */ FF(a, b, c, d, x(12), S11, 0x6b901122); /* 13 */ FF(d, a, b, c, x(13), S12, 0xfd987193); /* 14 */ FF(c, d, a, b, x(14), S13, 0xa679438e); /* 15 */ FF(b, c, d, a, x(15), S14, 0x49b40821); /* 16 *//* Round 2 */GG (a, b, c, d, x( 1), S21, 0xf61e2562); /* 17 */ GG (d, a, b, c, x( 6), S22, 0xc040b340); /* 18 */ GG (c, d, a, b, x(11), S23, 0x265e5a51); /* 19 */ GG (b, c, d, a, x( 0), S24, 0xe9b6c7aa); /* 20 */ GG (a, b, c, d, x( 5), S21, 0xd62f105d); /* 21 */ GG (d, a, b, c, x(10), S22, 0x2441453); /* 22 */ GG (c, d, a, b, x(15), S23, 0xd8a1e681); /* 23 */ GG (b, c, d, a, x( 4), S24, 0xe7d3fbc8); /* 24 */ GG (a, b, c, d, x( 9), S21, 0x21e1cde6); /* 25 */ GG (d, a, b, c, x(14), S22, 0xc33707d6); /* 26 */ GG (c, d, a, b, x( 3), S23, 0xf4d50d87); /* 27 */ GG (b, c, d, a, x( 8), S24, 0x455a14ed); /* 28 */ GG (a, b, c, d, x(13), S21, 0xa9e3e905); /* 29 */ GG (d, a, b, c, x( 2), S22, 0xfcefa3f8); /* 30 */ GG (c, d, a, b, x( 7), S23, 0x676f02d9); /* 31 */ GG (b, c, d, a, x(12), S24, 0x8d2a4c8a); /* 32 *//* Round 3 */HH (a, b, c, d, x( 5), S31, 0xfffa3942); /* 33 */HH (d, a, b, c, x( 8), S32, 0x8771f681); /* 34 */ HH (c, d, a, b, x(11), S33, 0x6d9d6122); /* 35 */ HH (b, c, d, a, x(14), S34, 0xfde5380c); /* 36 */ HH (a, b, c, d, x( 1), S31, 0xa4beea44); /* 37 */ HH (d, a, b, c, x( 4), S32, 0x4bdecfa9); /* 38 */ HH (c, d, a, b, x( 7), S33, 0xf6bb4b60); /* 39 */ HH (b, c, d, a, x(10), S34, 0xbebfbc70); /* 40 */ HH (a, b, c, d, x(13), S31, 0x289b7ec6); /* 41 */ HH (d, a, b, c, x( 0), S32, 0xeaa127fa); /* 42 */ HH (c, d, a, b, x( 3), S33, 0xd4ef3085); /* 43 */ HH (b, c, d, a, x( 6), S34, 0x4881d05); /* 44 */ HH (a, b, c, d, x( 9), S31, 0xd9d4d039); /* 45 */ HH (d, a, b, c, x(12), S32, 0xe6db99e5); /* 46 */ HH (c, d, a, b, x(15), S33, 0x1fa27cf8); /* 47 */ HH (b, c, d, a, x( 2), S34, 0xc4ac5665); /* 48 *//* Round 4 */II (a, b, c, d, x( 0), S41, 0xf4292244); /* 49 */ II (d, a, b, c, x( 7), S42, 0x432aff97); /* 50 */II (c, d, a, b, x(14), S43, 0xab9423a7); /* 51 */ II (b, c, d, a, x( 5), S44, 0xfc93a039); /* 52 */II (a, b, c, d, x(12), S41, 0x655b59c3); /* 53 */ II (d, a, b, c, x( 3), S42, 0x8f0ccc92); /* 54 */II (c, d, a, b, x(10), S43, 0xffeff47d); /* 55 */II (b, c, d, a, x( 1), S44, 0x85845dd1); /* 56 */ II (a, b, c, d, x( 8), S41, 0x6fa87e4f); /* 57 */II (d, a, b, c, x(15), S42, 0xfe2ce6e0); /* 58 */ II (c, d, a, b, x( 6), S43, 0xa3014314); /* 59 */ II (b, c, d, a, x(13), S44, 0x4e0811a1); /* 60 */ II (a, b, c, d, x( 4), S41, 0xf7537e82); /* 61 */II (d, a, b, c, x(11), S42, 0xbd3af235); /* 62 */ II (c, d, a, b, x( 2), S43, 0x2ad7d2bb); /* 63 */ II (b, c, d, a, x( 9), S44, 0xeb86d391); /* 64 */__asm{mov tmp1,DWORD PTR [state]add DWORD PTR [tmp1],aadd DWORD PTR [tmp1+4],badd DWORD PTR [tmp1+8],cadd DWORD PTR [tmp1+12],d}}//===================================================================== ===// MD5 for BCB//===================================================================== ===AnsiString __fastcall MD5_AnsiString(const AnsiString Input){int ok=0;MD5_CTX context;unsigned char digest[16], tmp[3], res[33]={0};try{MD5Init (&context);MD5Update (&context, Input.c_str(), Input.Length());MD5Final (&context, digest);ok=1;}catch(...){ok=0;}if(ok==1){for(int i=0;i<16;i++){sprintf(tmp,"%02x",digest[i]);strncat(res,tmp,2);}res[32]=0;}return AnsiString((char*)res);}AnsiString __fastcall MD5_File(const AnsiString FileName){int len, ok=0;FILE *fp=NULL;MD5_CTX context;unsigned char buffer[1024], digest[16], tmp[3], res[33]={0};if (NULL==(fp = fopen (FileName.c_str(), "rb")))return AnsiString("");else{try{try{MD5Init (&context);while (0!=(len = fread (buffer, 1, 1024, fp)))MD5Update (&context, buffer, len);MD5Final (&context, digest);ok=1;}catch(...){ok=0;}}__finally{fclose (fp);}if(ok==1){for(int i=0;i<16;i++){sprintf(tmp,"%02x",digest[i]);strncat(res,tmp,2);}res[32]=0;}}return AnsiString((char*)res);}//===================================================================== ===0000000000000000000000000000000000000000000000000000000000000000//---------------------------------------------------------------------------#include <windows.h>#include <stdio.h>/* Data structure for MD5 (Message-Digest) computation */typedef struct {ULONG i[2]; /* number of _bits_ handled mod 2^64 */ULONG buf[4]; /* scratch buffer */unsigned char in[64]; /* input buffer */unsigned char digest[16]; /* actual digest after MD5Final call */} MD5_CTX;#define MD5DIGESTLEN 16#define PROTO_LIST(list) list/** MTS: Each of these assumes MD5_CTX is locked against simultaneous use.*/typedef void (WINAPI* PMD5Init) PROTO_LIST ((MD5_CTX *));typedef void (WINAPI* PMD5Update) PROTO_LIST ((MD5_CTX *, const unsigned char *, uns igned int));typedef void (WINAPI* PMD5Final )PROTO_LIST ((MD5_CTX *));PMD5Init MD5Init = NULL;PMD5Update MD5Update = NULL;PMD5Final MD5Final = NULL;const char *Hex2ASC(const BYTE *Hex, int Len){static char ASC[4096 * 2];int i;for (i = 0; i < Len; i++){ASC[i * 2] = "0123456789ABCDEF"[Hex[i] >> 4];ASC[i * 2 + 1] = "0123456789ABCDEF"[Hex[i] & 0x0F];}ASC[i * 2] = '\0';return ASC;}int main(){MD5_CTX ctx;unsigned char buf[4] = "1234";HINSTANCE hDLL;if ( (hDLL = LoadLibrary("advapi32.dll")) > 0 ){MD5Init = (PMD5Init)GetProcAddress(hDLL,"MD5Init");MD5Update = (PMD5Update)GetProcAddress(hDLL,"MD5Update"); MD5Final = (PMD5Final)GetProcAddress(hDLL,"MD5Final");MD5Init(&ctx);MD5Update(&ctx,buf,4);MD5Final(&ctx);printf(Hex2ASC(ctx.digest,16));}return 0;}这样用就可以了,不记得在那里看到了,好像是nowcan写的。

C#:使用MD5对用户密码加密与解密

C#:使用MD5对用户密码加密与解密

C#:使⽤MD5对⽤户密码加密与解密C#中常涉及到对⽤户密码的加密于解密的算法,其中使⽤MD5加密是最常见的的实现⽅式。

本⽂总结了通⽤的算法并结合了⾃⼰的⼀点⼩经验,分享给⼤家。

⼀.使⽤16位、32位、64位MD5⽅法对⽤户名加密1)16位的MD5加密///<summary>/// 16位MD5加密///</summary>///<param name="password"></param>///<returns></returns>public static string MD5Encrypt16(string password){var md5 = new MD5CryptoServiceProvider();string t2 = BitConverter.ToString(puteHash(Encoding.Default.GetBytes(password)), 4, 8);t2 = t2.Replace("-", "");return t2;}2)32位的MD5加密///<summary>/// 32位MD5加密///</summary>///<param name="password"></param>///<returns></returns>public static string MD5Encrypt32(string password){string cl = password;string pwd = "";MD5 md5 = MD5.Create(); //实例化⼀个md5对像// 加密后是⼀个字节类型的数组,这⾥要注意编码UTF8/Unicode等的选择 byte[] s = puteHash(Encoding.UTF8.GetBytes(cl));// 通过使⽤循环,将字节类型的数组转换为字符串,此字符串是常规字符格式化所得for (int i = 0; i < s.Length; i++){// 将得到的字符串使⽤⼗六进制类型格式。

用c获取文件MD5值的实现方法

用c获取文件MD5值的实现方法

⽤c获取⽂件MD5值的实现⽅法⽹上有 md5.c , md5.h, 但是⾥⾯只有 MD5Init(), MD5Update(), MD5Final() 三个函数,只可以直接对字符进⾏操作, ⽽没有直接求⽂件md5的接⼝. 以下是我的实现, 可计算32位和16位的md5值.复制代码代码如下:#include <stdio.h>#include <stdlib.h>#include <string.h>#include "md5.h"char *MD5_file (char *path, int md5_len){FILE *fp = fopen (path, "rb");MD5_CTX mdContext;int bytes;unsigned char data[1024];char *file_md5;int i;if (fp == NULL) {fprintf (stderr, "fopen %s failed\n", path);return NULL;}MD5Init (&mdContext);while ((bytes = fread (data, 1, 1024, fp)) != 0){MD5Update (&mdContext, data, bytes);}MD5Final (&mdContext);file_md5 = (char *)malloc((md5_len + 1) * sizeof(char));if(file_md5 == NULL){fprintf(stderr, "malloc failed.\n");return NULL;}memset(file_md5, 0, (md5_len + 1));if(md5_len == 16){for(i=4; i<12; i++){sprintf(&file_md5[(i-4)*2], "%02x", mdContext.digest[i]);}}else if(md5_len == 32){for(i=0; i<16; i++){sprintf(&file_md5[i*2], "%02x", mdContext.digest[i]);}}else{fclose(fp);free(file_md5);return NULL;}int main(int argc, char *argv[]){char *md5;md5 = MD5_file("temp", 16);printf("16: %s\n", md5);free(md5);md5 = MD5_file("temp", 32);printf("32: %s\n", md5);free(md5);return 0;}以下是 md5.c的源码复制代码代码如下:#include "md5.h"/************************************************************************* md5.c **** RSA Data Security, Inc. MD5 Message Digest Algorithm ** ** Created: 2/17/90 RLR **** Revised: 1/91 SRD,AJ,BSK,JT Reference C Version ** ***********************************************************************//************************************************************************* Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. ** ** **** License to copy and use this software is granted provided that ** ** it is identified as the "RSA Data Security, Inc. MD5 Message ** ** Digest Algorithm" in all material mentioning or referencing this ** ** software or this function. **** **** License is also granted to make and use derivative works ** ** provided that such works are identified as "derived from the RSA ** ** Data Security, Inc. MD5 Message Digest Algorithm" in all **** material mentioning or referencing the derived work. **** **** RSA Data Security, Inc. makes no representations concerning ** ** either the merchantability of this software or the suitability **** of this software for any particular purpose. It is provided "as **** is" without express or implied warranty of any kind. **** **** These notices must be retained in any copies of any part of this ** ** documentation and/or software. *************************************************************************//* -- include the following line if the md5.h header file is separate -- */ /* #include "md5.h" *//* forward declaration */static void Transform ();static unsigned char PADDING[64] = {0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,};/* F, G and H are basic MD5 functions: selection, majority, parity */#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))#define H(x, y, z) ((x) ^ (y) ^ (z))#define I(x, y, z) ((y) ^ ((x) | (~z)))/* ROTATE_LEFT rotates x left n bits */#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4 *//* Rotation is separate from addition to prevent recomputation */#define FF(a, b, c, d, x, s, ac) \{(a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \(a) = ROTATE_LEFT ((a), (s)); \(a) += (b); \}#define GG(a, b, c, d, x, s, ac) \{(a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \(a) = ROTATE_LEFT ((a), (s)); \(a) += (b); \}#define HH(a, b, c, d, x, s, ac) \{(a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \(a) = ROTATE_LEFT ((a), (s)); \(a) += (b); \}#define II(a, b, c, d, x, s, ac) \{(a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \(a) = ROTATE_LEFT ((a), (s)); \(a) += (b); \}void MD5Init (MD5_CTX *mdContext){mdContext->i[0] = mdContext->i[1] = (UINT4)0;/* Load magic initialization constants.*/mdContext->buf[0] = (UINT4)0x67452301;mdContext->buf[1] = (UINT4)0xefcdab89;mdContext->buf[2] = (UINT4)0x98badcfe;mdContext->buf[3] = (UINT4)0x10325476;}void MD5Update (MD5_CTX *mdContext, unsigned char *inBuf, unsigned int inLen) {UINT4 in[16];int mdi;unsigned int i, ii;/* compute number of bytes mod 64 */mdi = (int)((mdContext->i[0] >> 3) & 0x3F);/* update number of bits */if ((mdContext->i[0] + ((UINT4)inLen << 3)) < mdContext->i[0])mdContext->i[1]++;mdContext->i[0] += ((UINT4)inLen << 3);mdContext->i[1] += ((UINT4)inLen >> 29);while (inLen--) {/* add new character to buffer, increment mdi */mdContext->in[mdi++] = *inBuf++;/* transform if necessary */if (mdi == 0x40) {for (i = 0, ii = 0; i < 16; i++, ii += 4)Transform (mdContext->buf, in);mdi = 0;}}}void MD5Final (MD5_CTX *mdContext){UINT4 in[16];int mdi;unsigned int i, ii;unsigned int padLen;/* save number of bits */in[14] = mdContext->i[0];in[15] = mdContext->i[1];/* compute number of bytes mod 64 */mdi = (int)((mdContext->i[0] >> 3) & 0x3F);/* pad out to 56 mod 64 */padLen = (mdi < 56) ? (56 - mdi) : (120 - mdi);MD5Update (mdContext, PADDING, padLen);/* append length in bits and transform */for (i = 0, ii = 0; i < 14; i++, ii += 4)in[i] = (((UINT4)mdContext->in[ii+3]) << 24) |(((UINT4)mdContext->in[ii+2]) << 16) |(((UINT4)mdContext->in[ii+1]) << 8) |((UINT4)mdContext->in[ii]);Transform (mdContext->buf, in);/* store buffer in digest */for (i = 0, ii = 0; i < 4; i++, ii += 4) {mdContext->digest[ii] = (unsigned char)(mdContext->buf[i] & 0xFF); mdContext->digest[ii+1] =(unsigned char)((mdContext->buf[i] >> 8) & 0xFF);mdContext->digest[ii+2] =(unsigned char)((mdContext->buf[i] >> 16) & 0xFF);mdContext->digest[ii+3] =(unsigned char)((mdContext->buf[i] >> 24) & 0xFF);}}/* Basic MD5 step. Transform buf based on in.*/static void Transform (UINT4 *buf, UINT4 *in){UINT4 a = buf[0], b = buf[1], c = buf[2], d = buf[3];/* Round 1 */#define S11 7#define S12 12#define S13 17#define S14 22FF ( a, b, c, d, in[ 0], S11, 3614090360); /* 1 */FF ( d, a, b, c, in[ 1], S12, 3905402710); /* 2 */FF ( c, d, a, b, in[ 2], S13, 606105819); /* 3 */FF ( b, c, d, a, in[ 3], S14, 3250441966); /* 4 */FF ( a, b, c, d, in[ 4], S11, 4118548399); /* 5 */FF ( d, a, b, c, in[ 5], S12, 1200080426); /* 6 */FF ( c, d, a, b, in[ 6], S13, 2821735955); /* 7 */FF ( b, c, d, a, in[ 7], S14, 4249261313); /* 8 */FF ( a, b, c, d, in[ 8], S11, 1770035416); /* 9 */FF ( d, a, b, c, in[ 9], S12, 2336552879); /* 10 */FF ( c, d, a, b, in[10], S13, 4294925233); /* 11 *//* Round 2 */#define S21 5#define S22 9#define S23 14#define S24 20GG ( a, b, c, d, in[ 1], S21, 4129170786); /* 17 */ GG ( d, a, b, c, in[ 6], S22, 3225465664); /* 18 */ GG ( c, d, a, b, in[11], S23, 643717713); /* 19 */ GG ( b, c, d, a, in[ 0], S24, 3921069994); /* 20 */ GG ( a, b, c, d, in[ 5], S21, 3593408605); /* 21 */ GG ( d, a, b, c, in[10], S22, 38016083); /* 22 */ GG ( c, d, a, b, in[15], S23, 3634488961); /* 23 */ GG ( b, c, d, a, in[ 4], S24, 3889429448); /* 24 */ GG ( a, b, c, d, in[ 9], S21, 568446438); /* 25 */ GG ( d, a, b, c, in[14], S22, 3275163606); /* 26 */ GG ( c, d, a, b, in[ 3], S23, 4107603335); /* 27 */ GG ( b, c, d, a, in[ 8], S24, 1163531501); /* 28 */ GG ( a, b, c, d, in[13], S21, 2850285829); /* 29 */ GG ( d, a, b, c, in[ 2], S22, 4243563512); /* 30 */ GG ( c, d, a, b, in[ 7], S23, 1735328473); /* 31 */ GG ( b, c, d, a, in[12], S24, 2368359562); /* 32 */ /* Round 3 */#define S31 4#define S32 11#define S33 16#define S34 23HH ( a, b, c, d, in[ 5], S31, 4294588738); /* 33 */ HH ( d, a, b, c, in[ 8], S32, 2272392833); /* 34 */ HH ( c, d, a, b, in[11], S33, 1839030562); /* 35 */ HH ( b, c, d, a, in[14], S34, 4259657740); /* 36 */ HH ( a, b, c, d, in[ 1], S31, 2763975236); /* 37 */ HH ( d, a, b, c, in[ 4], S32, 1272893353); /* 38 */ HH ( c, d, a, b, in[ 7], S33, 4139469664); /* 39 */ HH ( b, c, d, a, in[10], S34, 3200236656); /* 40 */ HH ( a, b, c, d, in[13], S31, 681279174); /* 41 */ HH ( d, a, b, c, in[ 0], S32, 3936430074); /* 42 */ HH ( c, d, a, b, in[ 3], S33, 3572445317); /* 43 */ HH ( b, c, d, a, in[ 6], S34, 76029189); /* 44 */ HH ( a, b, c, d, in[ 9], S31, 3654602809); /* 45 */ HH ( d, a, b, c, in[12], S32, 3873151461); /* 46 */ HH ( c, d, a, b, in[15], S33, 530742520); /* 47 */ HH ( b, c, d, a, in[ 2], S34, 3299628645); /* 48 */ /* Round 4 */#define S41 6#define S42 10#define S43 15#define S44 21II ( a, b, c, d, in[ 0], S41, 4096336452); /* 49 */ II ( d, a, b, c, in[ 7], S42, 1126891415); /* 50 */ II ( c, d, a, b, in[14], S43, 2878612391); /* 51 */ II ( b, c, d, a, in[ 5], S44, 4237533241); /* 52 */ II ( a, b, c, d, in[12], S41, 1700485571); /* 53 */ II ( d, a, b, c, in[ 3], S42, 2399980690); /* 54 */ II ( c, d, a, b, in[10], S43, 4293915773); /* 55 */ II ( b, c, d, a, in[ 1], S44, 2240044497); /* 56 */ II ( a, b, c, d, in[ 8], S41, 1873313359); /* 57 */ II ( d, a, b, c, in[15], S42, 4264355552); /* 58 */II ( b, c, d, a, in[ 9], S44, 3951481745); /* 64 */buf[0] += a;buf[1] += b;buf[2] += c;buf[3] += d;}/************************************************************************* End of md5.c ********************************* (cut) *********************************/以下是 md5.h 的源码复制代码代码如下:/************************************************************************* md5.h -- Header file for implementation of MD5 **** RSA Data Security, Inc. MD5 Message Digest Algorithm ** ** Created: 2/17/90 RLR **** Revised: 12/27/90 SRD,AJ,BSK,JT Reference C version ** ** Revised (for MD5): RLR 4/27/91 **** -- G modified to have y&~z instead of y&z **** -- FF, GG, HH modified to add in last register done **** -- Access pattern: round 2 works mod 5, round 3 works mod 3 ** ** -- distinct additive constant for each step **** -- round 4 added, working mod 7 *************************************************************************//************************************************************************* Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. ** ** **** License to copy and use this software is granted provided that ** ** it is identified as the "RSA Data Security, Inc. MD5 Message ** ** Digest Algorithm" in all material mentioning or referencing this ** ** software or this function. **** **** License is also granted to make and use derivative works ** ** provided that such works are identified as "derived from the RSA ** ** Data Security, Inc. MD5 Message Digest Algorithm" in all **** material mentioning or referencing the derived work. **** **** RSA Data Security, Inc. makes no representations concerning ** ** either the merchantability of this software or the suitability **** of this software for any particular purpose. It is provided "as **** is" without express or implied warranty of any kind. **** **** These notices must be retained in any copies of any part of this ** ** documentation and/or software. *************************************************************************//* typedef a 32 bit type */typedef unsigned long int UINT4;/* Data structure for MD5 (Message Digest) computation */typedef struct {UINT4 i[2]; /* number of _bits_ handled mod 2^64 */void MD5Init ();void MD5Update ();void MD5Final ();/*********************************************************************** ** End of md5.h ********************************* (cut) ******************************** */。

C语言实现MD5校验

C语言实现MD5校验

C语⾔实现MD5校验根据⽹上资料,整理验证C程序代码。

接⼝函数:1/******************************************************2*函数名称:Compute_data_md53*输⼊:data 校验数据⾸地址4 len 校验数据长度5 md5_str 字符串形式的MD5值6*输出:⽆7*功能:计算数据MD5值,并以字符串形式返回8*******************************************************/9int Compute_data_md5(unsigned char *data, unsigned int len,unsigned char *md5_str)View CodeMD5.h 的内容:1 #ifndef _MD5_H_2#define _MD5_H_34#define MD5_SIZE 165#define MD5_STR_LEN (MD5_SIZE * 2)67 typedef struct8 {9 unsigned int count[2];10 unsigned int state[4];11 unsigned char buffer[64];12 } MD5_CTX;1314#define F(x,y,z) ((x & y) | (~x & z))15#define G(x,y,z) ((x & z) | (y & ~z))16#define H(x,y,z) (x^y^z)17#define I(x,y,z) (y ^ (x | ~z))18#define ROTATE_LEFT(x,n) ((x << n) | (x >> (32-n)))1920#define FF(a,b,c,d,x,s,ac) \21 { \22 a += F(b,c,d) + x + ac; \23 a = ROTATE_LEFT(a,s); \24 a += b; \25 }26#define GG(a,b,c,d,x,s,ac) \27 { \28 a += G(b,c,d) + x + ac; \29 a = ROTATE_LEFT(a,s); \30 a += b; \31 }32#define HH(a,b,c,d,x,s,ac) \33 { \34 a += H(b,c,d) + x + ac; \35 a = ROTATE_LEFT(a,s); \36 a += b; \37 }38#define II(a,b,c,d,x,s,ac) \39 { \40 a += I(b,c,d) + x + ac; \41 a = ROTATE_LEFT(a,s); \42 a += b; \43 }44void MD5Init(MD5_CTX *context);45void MD5Update(MD5_CTX *context, unsigned char *input, unsigned int inputlen);46void MD5Final(MD5_CTX *context, unsigned char digest[16]);47void MD5Transform(unsigned int state[4], unsigned char block[64]);48void MD5Encode(unsigned char *output, unsigned int *input, unsigned int len);49void MD5Decode(unsigned int *output, unsigned char *input, unsigned int len);5051int Compute_data_md5(unsigned char *data, unsigned int len,unsigned char *md5_str);5253#endifView CodeMD5.c 的内容:1 #include "md5.h"2 #include <memory.h>3 #include <stdio.h>45 unsigned char PADDING[] =6 {70x80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,90,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,100,0,0,0,0,0,0,0,0,0,0,0,0,0,0,011 };1213void MD5Init(MD5_CTX *context)14 {15 context->count[0] = 0;16 context->count[1] = 0;17 context->state[0] = 0x67452301;18 context->state[1] = 0xEFCDAB89;19 context->state[2] = 0x98BADCFE;20 context->state[3] = 0x10325476;21 }2223void MD5Update(MD5_CTX *context, unsigned char *input, unsigned int inputlen)24 {25 unsigned int i = 0;26 unsigned int index = 0;27 unsigned int partlen = 0;2829 index = (context->count[0] >> 3) & 0x3F;30 partlen = 64 - index;31 context->count[0] += inputlen << 3;3233if(context->count[0] < (inputlen << 3))34 context->count[1]++;35 context->count[1] += inputlen >> 29;3637if(inputlen >= partlen)38 {39 memcpy(&context->buffer[index], input,partlen);40 MD5Transform(context->state, context->buffer);4142for(i = partlen; i+64 <= inputlen; i+=64)43 MD5Transform(context->state, &input[i]);4445 index = 0;46 }47else48 {49 i = 0;50 }51 memcpy(&context->buffer[index], &input[i], inputlen-i);52 }5354void MD5Final(MD5_CTX *context, unsigned char digest[16])55 {56 unsigned int index = 0,padlen = 0;57 unsigned char bits[8];5859 index = (context->count[0] >> 3) & 0x3F;60 padlen = (index < 56)?(56-index):(120-index);61 MD5Encode(bits, context->count, 8);62 MD5Update(context, PADDING, padlen);63 MD5Update(context, bits, 8);64 MD5Encode(digest, context->state, 16);65 }6667void MD5Encode(unsigned char *output,unsigned int *input,unsigned int len)68 {69 unsigned int i = 0;70 unsigned int j = 0;7172while(j < len)73 {74 output[j] = input[i] & 0xFF;75 output[j+1] = (input[i] >> 8) & 0xFF;76 output[j+2] = (input[i] >> 16) & 0xFF;77 output[j+3] = (input[i] >> 24) & 0xFF;78 i++;79 j += 4;80 }81 }8283void MD5Decode(unsigned int *output, unsigned char *input, unsigned int len)84 {85 unsigned int i = 0;86 unsigned int j = 0;8788while(j < len)89 {90 output[i] = (input[j]) |91 (input[j+1] << 8) |92 (input[j+2] << 16) |93 (input[j+3] << 24);94 i++;95 j += 4;96 }97 }9899void MD5Transform(unsigned int state[4], unsigned char block[64]) 100 {101 unsigned int a = state[0];102 unsigned int b = state[1];103 unsigned int c = state[2];104 unsigned int d = state[3];105 unsigned int x[64];106107 MD5Decode(x,block,64);108109 FF(a, b, c, d, x[ 0], 7, 0xd76aa478); /* 1 */110 FF(d, a, b, c, x[ 1], 12, 0xe8c7b756); /* 2 */111 FF(c, d, a, b, x[ 2], 17, 0x242070db); /* 3 */112 FF(b, c, d, a, x[ 3], 22, 0xc1bdceee); /* 4 */113 FF(a, b, c, d, x[ 4], 7, 0xf57c0faf); /* 5 */114 FF(d, a, b, c, x[ 5], 12, 0x4787c62a); /* 6 */115 FF(c, d, a, b, x[ 6], 17, 0xa8304613); /* 7 */116 FF(b, c, d, a, x[ 7], 22, 0xfd469501); /* 8 */117 FF(a, b, c, d, x[ 8], 7, 0x698098d8); /* 9 */118 FF(d, a, b, c, x[ 9], 12, 0x8b44f7af); /* 10 */119 FF(c, d, a, b, x[10], 17, 0xffff5bb1); /* 11 */120 FF(b, c, d, a, x[11], 22, 0x895cd7be); /* 12 */121 FF(a, b, c, d, x[12], 7, 0x6b901122); /* 13 */122 FF(d, a, b, c, x[13], 12, 0xfd987193); /* 14 */123 FF(c, d, a, b, x[14], 17, 0xa679438e); /* 15 */124 FF(b, c, d, a, x[15], 22, 0x49b40821); /* 16 */125126/* Round 2 */127 GG(a, b, c, d, x[ 1], 5, 0xf61e2562); /* 17 */128 GG(d, a, b, c, x[ 6], 9, 0xc040b340); /* 18 */129 GG(c, d, a, b, x[11], 14, 0x265e5a51); /* 19 */130 GG(b, c, d, a, x[ 0], 20, 0xe9b6c7aa); /* 20 */131 GG(a, b, c, d, x[ 5], 5, 0xd62f105d); /* 21 */132 GG(d, a, b, c, x[10], 9, 0x2441453); /* 22 */133 GG(c, d, a, b, x[15], 14, 0xd8a1e681); /* 23 */134 GG(b, c, d, a, x[ 4], 20, 0xe7d3fbc8); /* 24 */135 GG(a, b, c, d, x[ 9], 5, 0x21e1cde6); /* 25 */136 GG(d, a, b, c, x[14], 9, 0xc33707d6); /* 26 */137 GG(c, d, a, b, x[ 3], 14, 0xf4d50d87); /* 27 */138 GG(b, c, d, a, x[ 8], 20, 0x455a14ed); /* 28 */139 GG(a, b, c, d, x[13], 5, 0xa9e3e905); /* 29 */140 GG(d, a, b, c, x[ 2], 9, 0xfcefa3f8); /* 30 */141 GG(c, d, a, b, x[ 7], 14, 0x676f02d9); /* 31 */142 GG(b, c, d, a, x[12], 20, 0x8d2a4c8a); /* 32 */143144/* Round 3 */145 HH(a, b, c, d, x[ 5], 4, 0xfffa3942); /* 33 */146 HH(d, a, b, c, x[ 8], 11, 0x8771f681); /* 34 */147 HH(c, d, a, b, x[11], 16, 0x6d9d6122); /* 35 */148 HH(b, c, d, a, x[14], 23, 0xfde5380c); /* 36 */149 HH(a, b, c, d, x[ 1], 4, 0xa4beea44); /* 37 */150 HH(d, a, b, c, x[ 4], 11, 0x4bdecfa9); /* 38 */151 HH(c, d, a, b, x[ 7], 16, 0xf6bb4b60); /* 39 */152 HH(b, c, d, a, x[10], 23, 0xbebfbc70); /* 40 */153 HH(a, b, c, d, x[13], 4, 0x289b7ec6); /* 41 */154 HH(d, a, b, c, x[ 0], 11, 0xeaa127fa); /* 42 */155 HH(c, d, a, b, x[ 3], 16, 0xd4ef3085); /* 43 */156 HH(b, c, d, a, x[ 6], 23, 0x4881d05); /* 44 */157 HH(a, b, c, d, x[ 9], 4, 0xd9d4d039); /* 45 */158 HH(d, a, b, c, x[12], 11, 0xe6db99e5); /* 46 */159 HH(c, d, a, b, x[15], 16, 0x1fa27cf8); /* 47 */160 HH(b, c, d, a, x[ 2], 23, 0xc4ac5665); /* 48 */161162/* Round 4 */163 II(a, b, c, d, x[ 0], 6, 0xf4292244); /* 49 */164 II(d, a, b, c, x[ 7], 10, 0x432aff97); /* 50 */165 II(c, d, a, b, x[14], 15, 0xab9423a7); /* 51 */166 II(b, c, d, a, x[ 5], 21, 0xfc93a039); /* 52 */167 II(a, b, c, d, x[12], 6, 0x655b59c3); /* 53 */168 II(d, a, b, c, x[ 3], 10, 0x8f0ccc92); /* 54 */169 II(c, d, a, b, x[10], 15, 0xffeff47d); /* 55 */170 II(b, c, d, a, x[ 1], 21, 0x85845dd1); /* 56 */171 II(a, b, c, d, x[ 8], 6, 0x6fa87e4f); /* 57 */172 II(d, a, b, c, x[15], 10, 0xfe2ce6e0); /* 58 */173 II(c, d, a, b, x[ 6], 15, 0xa3014314); /* 59 */174 II(b, c, d, a, x[13], 21, 0x4e0811a1); /* 60 */175 II(a, b, c, d, x[ 4], 6, 0xf7537e82); /* 61 */176 II(d, a, b, c, x[11], 10, 0xbd3af235); /* 62 */177 II(c, d, a, b, x[ 2], 15, 0x2ad7d2bb); /* 63 */178 II(b, c, d, a, x[ 9], 21, 0xeb86d391); /* 64 */179 state[0] += a;180 state[1] += b;181 state[2] += c;182 state[3] += d;183 }184185186/******************************************************187*函数名称:Compute_data_md5188*输⼊:data 校验数据⾸地址189 len 校验数据长度190 md5_str 字符串形式的MD5值191*输出:⽆192*功能:计算数据MD5值,并以字符串形式返回193*******************************************************/194int Compute_data_md5(unsigned char *data, unsigned int len,unsigned char *md5_str) 195 {196 unsigned char md5_value[MD5_SIZE];197 unsigned int i = 0;198199 MD5_CTX md5;200201 MD5Init(&md5);202 MD5Update(&md5, data, len);203 MD5Final(&md5, md5_value);204for(i = 0; i < MD5_SIZE; i++)205 {206 snprintf(md5_str + i*2, 2+1, "%02x", md5_value[i]);207 }208 md5_str[MD5_STR_LEN] = '\0'; // add end209 }210211#if 0212int Compute_file_md5(const char *file_path, char *md5_str)213 {214int i;215int fd;216int ret;217 unsigned char data[READ_DATA_SIZE];218 unsigned char md5_value[MD5_SIZE];219 MD5_CTX md5;220221 fd = open(file_path, O_RDONLY);222if (-1 == fd)223 {224 perror("open");225return -1;226 }227228// init md5229 MD5Init(&md5);230231while (1)232 {233 ret = read(fd, data, READ_DATA_SIZE);234if (-1 == ret)235 {236 perror("read");237return -1;238 }239240 MD5Update(&md5, data, ret);241242if (0 == ret || ret < READ_DATA_SIZE)243 {244break;245 }246 }247248 close(fd);249250 MD5Final(&md5, md5_value);251252for(i = 0; i < MD5_SIZE; i++)253 {254 snprintf(md5_str + i*2, 2+1, "%02x", md5_value[i]); 255 }256 md5_str[MD5_STR_LEN] = '\0'; // add end257258return0;259 }260#endifView Code。

C语言实现MD5算法

C语言实现MD5算法

C语言实现MD5算法1.理解MD5算法原理:-MD5算法是一种常用的哈希函数,用于将任意长度的消息转换为固定长度的哈希值,通常为128位。

-MD5算法主要包括四个循环运算和四个非线性函数,通过迭代运算将输入的消息分块处理并输出最终的哈希值。

2.定义MD5算法所需的常量和函数:-定义一个64个元素的常数列表,用于在算法运算中使用。

-定义四个非线性的F,G,H,I函数,用于在循环运算中使用。

3.定义MD5算法所需的全局变量:-定义一个128位的缓冲区保存最终输出的哈希值。

-定义一个64位的计数指示器,记录输入消息的长度。

-定义四个32位的寄存器变量A、B、C、D,用于循环运算过程中保存中间结果。

4.实现MD5算法的主要函数:- 实现Padding函数,将输入消息按照MD5算法的规则进行填充,使其长度满足对512位的整数倍。

-实现FF,GG,HH,II四个函数,用于在每个循环运算中进行非线性转换。

-实现MD5算法的核心循环函数,将输入消息分块处理,并对每个分块进行四轮循环运算,更新寄存器变量的值。

-实现MD5算法的输出函数,将最终运算得到的寄存器变量的值按照一定顺序连接起来,得到最终的128位哈希值。

5.实现MD5算法的入口函数:- 在main函数中,读取输入消息,并调用MD5算法的相关函数,得到最终的哈希值。

-打印输出哈希值。

以下为C语言实现MD5算法的伪代码:```c//定义MD5算法所需的常量和函数const uint32_t s[64] = { ... }; // 常数表const uint32_t k[64] = { ... }; // F,G,H,I函数对应的逻辑常数uint32_t F(uint32_t x, uint32_t y, uint32_t z) { ... } // F 函数uint32_t G(uint32_t x, uint32_t y, uint32_t z) { ... } // G 函数uint32_t H(uint32_t x, uint32_t y, uint32_t z) { ... } // H 函数uint32_t I(uint32_t x, uint32_t y, uint32_t z) { ... } // I 函数//定义MD5算法所需的全局变量uint32_t buffer[4]; // 128位缓冲区uint64_t count = 0; // 输入消息的长度uint32_t A, B, C, D; // 寄存器变量// 实现Padding函数void padding(char* message) { ... }//实现FF,GG,HH,II四个函数void FF(...) { ... }void GG(...) { ... }void HH(...) { ... }void II(...) { ... }//实现MD5算法的核心循环函数void MD5Block(uint32_t* block) { ... }//实现MD5算法的输出函数void MD5Output(uint32_t* digest) { ... }//实现MD5算法的入口函数int maichar message[MAX_LENGTH];uint32_t digest[4];//读取输入消息gets(message);//填充输入消息padding(message);//分块处理for (uint32_t i = 0; i < count; i += 64)MD5Block(&message[i]);}//输出最终结果MD5Output(digest);//打印哈希值printf("%08x%08x%08x%08x", digest[0], digest[1], digest[2], digest[3]);return 0;```以上是一个简单的伪代码,实现了C语言下的MD5算法。

md5加密算法的C(C++)代码实现-3

md5加密算法的C(C++)代码实现-3

引用:/Articles/ …… /Arithmetic/MD5.htm

第四轮
ii(a,b,c,d,m0,6,0xf4292244)
ii(d,a,b,c,m7,10,0x432aff97)
ii(c,d,a,b,m14,15,0xab9423a7)
ii(b,c,d,a,m5,21,0xfc93a039)
ii(a,b,c,d,m12,6,0x655b59c3)
ii(c,d,a,b,m6,15,0xa3014314)
ii(b,c,d,a,m13,21,0x4e0811a1)
ii(a,b,c,d,m4,6,0xf7537e82)
ii(d,a,b,c,m11,10,0xbd3af235)
ii(c,d,a,b,m2,15,0x2ad7d2bb)
如果你用上面的信息分别对你做的md5算法实例做测试,最后得出的结论和标准答案完全一样,那我就要在这里象你道一声祝贺了。要知道,我的程序在第一次编译成功的时候是没有得出和上面相同的结果的。
MD5的安全性
md5相对md4所作的改进:
1. 增加了第四轮;
2. 每一步均有唯一的加法常数;
ii(d,a,b,c,m3,10,0x8f0ccc92)
ii(c,d,a,b,m10,15,0xffeff47d)
ii(b,c,d,a,m1,21,0x85845dd1)
ii(a,b,c,d,m8,6,0x6fa87e4f)
ii(d,a,b,c,m15,10,0xfe2ce6e0)
ii(b,c,d,a,m9,21,0xeb86d391)
常数ti可以如下选择:
在第i步中,ti是4294967296*abs(sin(i))的整数部分,i的单位是弧度。(4294967296等于2的32次方)
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

正是因为这个原因,现在被黑客使用最多的一种破译密码的方法就是一种被称为"跑字典"的方法。有两种方法得到字典,一种是日常搜集的用做密码的字符串表,另一种是用排列组合方法生成的,先用md5程序计算出这些字典项的md5值,然后再用目标的md5值在这个字典中检索。我们假设密码的最大长度为8位字节(8 bytes),同时密码只能是字母和数字,共26+26+10=62个字符,排列组合出的字典的项数则是p(62,1)+p(62,2)…。+p(62,8),那也已经是一个很天文的数字了,存储这个字典就需要tb级的磁盘阵列,而且这种方法还有一个前提,就是能获得目标账户的密码md5值的情况下才可以。这种加密技术被广泛的应用于unix系统中,这也是为什么unix系统比一般操作系统更为坚固一个重要原因。
<< 这四轮(64步)是:
第一轮
ff(a,b,c,d,m0,7,0xd76aa478)
ff(d,a,b,c,m1,12,0xe8c7b756)
ff(c,d,a,b,m2,17,0x242070db)
ff(b,c,d,a,m3,22,0xc1bdceee)
将上面四个链接变量复制到另外四个变量中:a到a,b到b,c到c,d到d.
主循环有四轮(md4只有三轮),每轮循环都很相似。第一轮进行16次操作。每次操作对a、b、c和d中的其中三个作一次非线性函数运算,然后将所得结果加上第四个变量,文本的一个子分组和一个常数。再将所得结果向右环移一个不定的数,并加上a、b、c或d中之一。最后用该结果取代a、b、c或d中之一。
rivest在1989年开发出md2算法。在这个算法中,首先对信息进行数据补位,使信息的字节长度是16的倍数。然后,以一个16位的检验和追加到信息末尾。并且根据这个新产生的信息计算出散列值。后来,rogier和chauvaud发现如果忽略了检验和将产生md2冲突。md2算法的加密后结果是唯一的——既没有重复。
为了加强算法的安全性,rivest在1990年又开发出md4算法。md4算法同样需要填补信息以确保信息的字节长度加上448后能被512整除(信息字节长度mod 512 = 448)。然后,一个以64位二进制表示的信息的最初长度被添加进来。信息被处理成512位damg?rd/merkle迭代结构的区块,而且每个区块要通过三个不同步骤的处理。den boer和bosselaers以及其他人很快的发现了攻击md4版本中第一步和第三步的漏洞。dobbertin向大家演示了如何利用一部普通的个人电脑在几分钟内找到md4完整版本中的冲突(这个冲突实际上是一种漏洞,它将导致对不同的内容进行加密却可能得到相同的加密后结果)。毫无疑问,md4就此被淘汰掉了。
以一下是每次操作中用到的四个非线性函数(每轮一个)。
f(x,y,z) =(x&y)|((~x)&z)
g(x,y,z) =(x&z)|(y&(~z))
h(x,y,z) =x^y^z i(x,y,z)=y^(x|(~z))
(&是与,|是或,~是非,^是异或)
md5中有四个32位被称作链接变量(chaining variable)的整数参数,他们分别为:a=0x01234567,b=0x89abcdef,c=0xfedcba98,d=0x76543210.
当设置好这四个链接变量后,就开始进入算法的四轮循环运算。循环的次数是信息中512位信息分组的数目。
van oorschot和wiener曾经考虑过一个在散列中暴力搜寻冲突的函数(brute-force hash function),而且他们猜测一个被设计专门用来搜索md5冲突的机器(这台机器在1994年的制造成本大约是一百万美元)可以平均每24天就找到一个冲突。但单从1991年到2001年这10年间,竟没有出现替代md5算法的md6或被叫做其他什么名字的新算法这一点,我们就可以看出这个瑕疵并没有太多的影响md5的安全性。上面所有这些都不足以成为md5的在实际应用中的问题。并且,由于md5算法的使用不需要支付任何版权费用的,所以在一般的情况下(非绝密应用领域。但即便是应用在绝密领域内,md5也不失为一种非常优秀的中间技术),md5怎么都应该算得上是非常安全的了。
这四个函数的说明:如果x、y和z的对应位是独立和均匀的,那么结果的每一位也应是独立和均匀的。
f是一个逐位运算的函数。即,如果x,那么y,否则z.函数h是逐位奇偶操作符。
假设mj表示消息的第j个子分组(从0到15),<< ff(a,b,c,d,mj,s,ti) 表示 a=b+((a+(f(b,c,d)+mj+ti)
gg(a,b,c,d,m9,5,0x21e1cde6)
gg(d,a,b,c,m14,9,0xc33707d6)
gg(c,d,a,b,m3,14,0xf4d50d87)
gg(b,c,d,a,m8,20,0x455a14ed)
gg(a,b,c,d,m13,5,0xa9e3e905)
这就是tanajiya.tar.gz文件的数字签名。md5将整个文件当作一个大文本信息,通过其不可逆的字符串变换算法,产生了这个唯一的md5信息摘要。如果在以后传播这个文件的过程中,无论文件的内容发生了任何形式的改变(包括人为修改或者下载过程中线路不稳定引起的传输错误等),只要你对这个文件重新计算md5时就会发现信息摘要不相同,由此可以确定你得到的只是一个不正确的文件。如果再有一个第三方的认证机构,用md5还可以防止文件作者的"抵赖",这就是所谓的数字签名应用。
gg(b,c,d,a,m0,20,0xe9b6c7aa)
gg(a,b,c,d,m5,5,0xd62f105d)
gg(d,a,b,c,m10,9,0x02441453)
gg(c,d,a,b,m15,14,0xd8a1e681)
gg(b,c,d,a,m4,20,0xe7d3fbc8)
算法的应用
md5的典型应用是对一段信息(message)产生信息摘要(message-digest),以防止被篡改。比如,在unix下有很多软件在下载的时候都有一个文件名相同,文件扩展名为。md5的文件,在这个文件中通常只有一行文本,大致结构如:
md5 (tanajiya.tar.gz) = 0ca175b9c0f726a831d895e269332461
gg(d,a,b,c,m2,9,ห้องสมุดไป่ตู้xfcefa3f8)
gg(c,d,a,b,m7,14,0x676f02d9)
gg(b,c,d,a,m12,20,0x8d2a4c8a)
第三轮
ff(a,b,c,d,m4,7,0xf57c0faf)
ff(d,a,b,c,m5,12,0x4787c62a)
ff(c,d,a,b,m6,17,0xa8304613)
ff(b,c,d,a,m7,22,0xfd469501)
ff(a,b,c,d,m8,7,0x698098d8)
md5还广泛用于加密和解密技术上。比如在unix系统中用户的密码就是以md5(或其它类似的算法)经加密后存储在文件系统中。当用户登录的时候,系统把用户输入的密码计算成md5值,然后再去和保存在文件系统中的md5值进行比较,进而确定输入的密码是否正确。通过这样的步骤,系统在并不知道用户密码的明码的情况下就可以确定用户登录系统的合法性。这不但可以避免用户的密码被具有系统管理员权限的用户知道,而且还在一定程度上增加了密码被破解的难度。
md5加密算法的C(C++)代码实现(完整)
MD5的全称是message-digest algorithm 5(信息-摘要算法),在90年代初由mit laboratory for computer science和rsa data security inc的ronald l. rivest开发出来,经md2、md3和md4发展而来。它的作用是让大容量信息在用数字签名软件签署私人密匙前被"压缩"成一种保密的格式(就是把一个任意长度的字节串变换成一定长的大整数)。不管是md2、md4还是md5,它们都需要获得一个随机长度的信息并产生一个128位的信息摘要。虽然这些算法的结构或多或少有些相似,但md2的设计与md4和md5完全不同,那是因为md2是为8位机器做过设计优化的,而md4和md5却是面向32位的电脑。这三个算法的描述和c语言源代码在internet rfcs 1321中有详细的描述(/rfc/rfc1321.txt)/*在本文下面是这篇文章*/,这是一份最权威的文档,由ronald l. rivest在1992年8月向ieft提交。
<< gg(a,b,c,d,mj,s,ti) 表示 a=b+((a+(g(b,c,d)+mj+ti)
<< hh(a,b,c,d,mj,s,ti) 表示 a=b+((a+(h(b,c,d)+mj+ti)
<< ii(a,b,c,d,mj,s,ti) 表示 a=b+((a+(i(b,c,d)+mj+ti)
ff(c,d,a,b,m14,17,0xa679438e)
ff(b,c,d,a,m15,22,0x49b40821)
第二轮
gg(a,b,c,d,m1,5,0xf61e2562)
gg(d,a,b,c,m6,9,0xc040b340)
gg(c,d,a,b,m11,14,0x265e5a51)
ff(d,a,b,c,m9,12,0x8b44f7af)
ff(c,d,a,b,m10,17,0xffff5bb1)
ff(b,c,d,a,m11,22,0x895cd7be)
ff(a,b,c,d,m12,7,0x6b901122)
相关文档
最新文档