淺談md5加密 以及C++實現
md5加密是我們生活中十分常見的加密演算法。
起因:我是最近在寫一個H5 的專案時接觸到的這個演算法,這個演算法極大的引起了我的好奇心,是登陸介面,要求是將使用者輸入的密碼使用md5加密之後,再傳回伺服器,當時我十分不理解原因是什麼.
廢話少說
原因
1、密碼在前端進行加密,然後伺服器使用摘要進行比對,這樣在整個密碼的校驗過程中是在伺服器端不知道明碼的情況下進行的,極大的保證了密碼的安全,試想一下,一個銀行管理員,如果他可以通過伺服器獲取到明文密碼,那麼他一旦變心了,咋辦,那豈不是太危險,所以通過md5加密便很好地解決了這個問題
2、在避免檔案內容被篡改方面有重大作用,md5可以對字串進行不可逆的加密,這使得可以生成一個128bit的大數,由於md5演算法的原因,他與原始檔相對應,即使在檔案中做了很小的修改,那麼生成的字串也是差別巨大
3、在破解md5方面,最常用的方法是“跑字典”,有兩種方法得到字典,一種是日常蒐集的用做密碼的字串表,另一種是用排列組合方法生成的,先用MD5程式計算出這些字典項的MD5值,然後再用目標的MD5值在這個字典中檢索。我們假設密碼的最大長度為8位位元組(8 Bytes),同時密碼只能是字母和數字,共26+26+10=62個位元組,排列組合出的字典的項數則是P(62,1)+P(62,2)….+P(62,8),那也已經是一個很天文的數字了,儲存這個字典就需要TB級的磁碟陣列,而且這種方法還有一個前提,就是能獲得目標賬戶的密碼MD5值的情況下才可以。
所以總體而言,md5加密是十分安全的,即使有一些瑕疵,但並不影響具體的使用,外加md5是免費的,所以它的應用還是十分廣泛的
附加一份C++的md5加密演算法原始碼
#include<iostream>
#include<string>
using namespace std;
#define shift(x, n) (((x) << (n)) | ((x) >> (32-(n))))//右移的時候,高位一定要補零,而不是補充符號位
#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)))
#define A 0x67452301
#define B 0xefcdab89
#define C 0x98badcfe
#define D 0x10325476
//strBaye的長度
unsigned int strlength;
//A,B,C,D的臨時變數
unsigned int atemp;
unsigned int btemp;
unsigned int ctemp;
unsigned int dtemp;
//常量ti unsigned int(abs(sin(i+1))*(2pow32))
const unsigned int k[]={
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};
//向左位移數
const unsigned int s[]={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};
const char str16[]="0123456789abcdef";
void mainLoop(unsigned int M[])
{
unsigned int f,g;
unsigned int a=atemp;
unsigned int b=btemp;
unsigned int c=ctemp;
unsigned int d=dtemp;
for (unsigned int i = 0; i < 64; i++)
{
if(i<16){
f=F(b,c,d);
g=i;
}else if (i<32)
{
f=G(b,c,d);
g=(5*i+1)%16;
}else if(i<48){
f=H(b,c,d);
g=(3*i+5)%16;
}else{
f=I(b,c,d);
g=(7*i)%16;
}
unsigned int tmp=d;
d=c;
c=b;
b=b+shift((a+f+k[i]+M[g]),s[i]);
a=tmp;
}
atemp=a+atemp;
btemp=b+btemp;
ctemp=c+ctemp;
dtemp=d+dtemp;
}
/*
*填充函式
*處理後應滿足bits≡448(mod512),位元組就是bytes≡56(mode64)
*填充方式為先加一個1,其它位補零
*最後加上64位的原來長度
*/
unsigned int* add(string str)
{
unsigned int num=((str.length()+8)/64)+1;//以512位,64個位元組為一組
unsigned int *strByte=new unsigned int[num*16]; //64/4=16,所以有16個整數
strlength=num*16;
for (unsigned int i = 0; i < num*16; i++)
strByte[i]=0;
for (unsigned int i=0; i <str.length(); i++)
{
strByte[i>>2]|=(str[i])<<((i%4)*8);//一個整數儲存四個位元組,i>>2表示i/4 一個unsigned int對應4個位元組,儲存4個字元資訊
}
strByte[str.length()>>2]|=0x80<<(((str.length()%4))*8);//尾部新增1 一個unsigned int儲存4個字元資訊,所以用128左移
/*
*新增原長度,長度指位的長度,所以要乘8,然後是小端序,所以放在倒數第二個,這裡長度只用了32位
*/
strByte[num*16-2]=str.length()*8;
return strByte;
}
string changeHex(int a)
{
int b;
string str1;
string str="";
for(int i=0;i<4;i++)
{
str1="";
b=((a>>i*8)%(1<<8))&0xff; //逆序處理每個位元組
for (int j = 0; j < 2; j++)
{
str1.insert(0,1,str16[b%16]);
b=b/16;
}
str+=str1;
}
return str;
}
string getMD5(string source)
{
atemp=A; //初始化
btemp=B;
ctemp=C;
dtemp=D;
unsigned int *strByte=add(source);
for(unsigned int i=0;i<strlength/16;i++)
{
unsigned int num[16];
for(unsigned int j=0;j<16;j++)
num[j]=strByte[i*16+j];
mainLoop(num);
}
return changeHex(atemp).append(changeHex(btemp)).append(changeHex(ctemp)).append(changeHex(dtemp));
}
int main()
{
string ss;
// cin>>ss;
string s=getMD5("456");
cout<<s;
return 0;
}
引自:https://blog.csdn.net/qq_32635069/article/details/72860033
相關文章
- C# 實現MD5加密處理 MD5 加密C#加密
- qt實現md5加密QT加密
- java MD5 加密實現Java加密
- Javascript實現MD5加密JavaScript加密
- python 實現md5加密Python加密
- Golang兩種方法實現MD5加密Golang加密
- java實現MD5加鹽加密方法Java加密
- MD5演算法--C++實現演算法C++
- 淺談加密技術加密
- 淺談常見的七種加密演算法及實現加密演算法
- JavaScript實現的base64加密、md5加密、sha1加密及AES加密JavaScript加密
- 利用 C++ 實現 md5 演算法C++演算法
- 淺談react diff實現React
- C語言實現MD5加密,竟如此簡單!C語言加密
- 淺談C++物理設計:實用巨集C++
- 淺談Innodb的鎖實現
- MD5加密加密
- C++ string (淺談)C++
- 談談 Promise 以及實現 Fetch 的思路Promise
- 談談限流演算法,以及Redisson實現演算法Redis
- 淺談達夢DSC叢集以及負載均衡實現與驗證負載
- 前端動畫實現以及原理淺析前端動畫
- 淺談微積分以及泰勒展開
- 淺談VueUse設計與實現Vue
- 淺談持續整合的理解以及實現持續整合,需要做什麼?
- java MD5 加密Java加密
- 【Java】MD5加密Java加密
- md5加密解密加密解密
- iOS MD5加密iOS加密
- java md5加密Java加密
- C++中的enum淺談C++
- 淺談IAT加密原理及過程加密
- 淺談Vue中的資料繫結的實現,以及Vue3.0的proxyVue
- 淺談前端安全以及如何防範前端
- 淺談Generator和Promise原理及實現Promise
- 淺談如何實現自定義的 iterator
- 淺談php變數的實現-PHPPHP變數
- 淺談Node中module的實現原理