1. 程式人生 > >淺談md5加密 以及C++實現

淺談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; }

相關推薦

md5加密 以及C++實現

md5加密是我們生活中十分常見的加密演算法。 起因:我是最近在寫一個H5 的專案時接觸到的這個演算法,這個演算法極大的引起了我的好奇心,是登陸介面,要求是將使用者輸入的密碼使用md5加密之後,再傳回伺服器,當時我十分不理解原因是什麼. 廢話少說 原因

MD5加密演算法中的加鹽值(SALT)

我們知道,如果直接對密碼進行雜湊,那麼黑客可以對通過獲得這個密碼雜湊值,然後通過查雜湊值字典(例如MD5密碼破解網站),得到某使用者的密碼。   加Salt可以一定程度上解決這一問題。所謂加Salt方法,就是加點“佐料”。其基本想法是這樣的:當用戶首次提供密碼時(通常是

MD5加密演算法C語言實現

md5.h #ifndef MD5_H #define MD5_H typedef struct { unsigned int count[2]; unsigned int state[4]; unsigned char buffe

短連結以及一種不同的實現方案

一個月前參加某網際網路公司的校招筆試時被問到:該如何實現一個短連結服務? 當時隨便寫了點和伺服器架構相關的東西上去,實際上我並不知道短連結是如何解析的,這兩天在實習的時候想起了這個問題,便學習了一下。 目前比較通用的做法是建立一張 id , url 的表,id通過自增保證

多型以及php的實現方法

先簡單說一下多型 多型的三大特徵: 子類繼承父類 子類重寫父類 父類指向子類 多型實現的前提:必須是類與類之間要有關係,要麼繼承,要麼實現,存在重寫(override),其實就是抽象函式或介面。 多型的應用:父類物件的引用指向子類物件,其實本質上就是

JAVA中使用MD5加密工具類實現對數據的加密處理

歸納 ssa utf int 控制 nic this com nod 1.MD5工具類 package com.ssm.util; import java.security.MessageDigest; public class MD5Util { //將字

1.3Spring(IOC容器的實現)

tap 就是 parser pojo file abstract throw cdd moni 這一節我們來討論IOC容器到底做了什麽。 還是借用之前的那段代碼 ClassPathXmlApplicationContext app = new ClassPathXmlAp

分散式鎖--基於Zookeeper實現

淺談分散式鎖--基於Zookeeper實現篇: 1、基於zookeeper臨時有序節點可以實現的分散式鎖。其實基於ZooKeeper,就是使用它的臨時有序節點來實現的分散式鎖。 來看下Zookeeper能不能解決前面提到的問題。     鎖無法釋放:使用

分散式鎖--基於資料庫實現

淺談分散式鎖--基於資料庫實現篇 1、基於資料庫表     要實現分散式鎖,最簡單的方式可能就是直接建立一張鎖表,然後通過操作該表中的資料來實現了。     當我們要鎖住某個方法或資源時,我們就在該表中增加一條記錄,想要釋放鎖的

JavaScript模擬$(HTML字串)實現建立DOM物件

JavaScript裡動態建立標準DOM物件一般使用:document.createElement()方法。 但在實際使用過程中,可能會希望直接根據HTML字串建立DOM節點,模擬$(HTML字串)建立DOM物件的方法。 1、思路: ① 用document.createElement()

MD5加密演算法Golang實現

什麼是MD5? MD5訊息摘要演算法(Message-Digest Algorithm),一種被廣泛使用的密碼雜湊函式,可以產生出一個128位(16位元組)的雜湊值,用於確保資訊傳輸完整一致。MD5有MD4、MD3、MD2改進而來,主要增強演算法複雜度和不可逆性。MD5廣泛使用在為檔案傳

base64加密演算法C++實現

  base64編碼原理:維基百科 - Base64   其實編碼規則很簡單,將字串按每三個字元組成一組,因為每個字元的 ascii 碼對應 0~127 之間(顯然,不考慮其他字符集編碼),即每個字元的二進位制以 8 bit 儲存,$ 3 \times 8 = 4 \times 6 $,這樣就可以很方便的轉

矩陣分解以及應用

轉自 https://blog.csdn.net/BPSSY/article/details/17552839 https://blog.csdn.net/carrierlxksuper/article/details/8487276 矩陣分解 (matrix decomposit

AES加密演算法C++實現

(1)aes.h #ifndef aes_h__ #define aes_h__ class AES { public: AES(unsigned char* key); virtual ~AES(); unsigned char* Cipher(unsigned char* inpu

Swift和Objective-C之間的那點事。。。

Swift 是一種新的程式語言,用於編寫 iOS 和 OS X 應用。Swift 結合了 C 和 Objective-C 的優點並且不受C相容性的限制。Swift 採用安全的程式設計模式並添加了很多新特性,這將使程式設計更簡單,更靈活,也更有趣。Swift 是基

各種排序演算法的場景以及c++實現(插入排序,希爾排序,氣泡排序,快速排序,選擇排序,歸併排序)

對現有工作並不是很滿意,所以決定找下一個坑。由工作中遇到排序場景並不多,大都是用氣泡排序,太low,面試又經常問到一些排序演算法方面的東西。剛好讓小學妹郵的資料結構也到了。就把各種排序演算法重新總結一下,以作留存。 排序分為內部排序和外部排序,內部排序是在記憶體中排序。外

B樹的原理以及C++實現(附原始碼和文件)

B樹的C++實現 之前課程設計做的一個BTrees資料結構,在這裡添加了演算法說明的PDF文件以及配套的Latex文件,同時有原始碼和詳細的說明,演算法思路全部來自於演算法導論,,需要的同學直接拿走。

MD5演算法的C++實現

1. Introduction MD5演算法是一種訊息摘要演算法(Message Digest Algorithm),此演算法以任意長度的資訊(message)作為輸入進行計算,產生一個128-bit(16-byte)的指紋或報文摘要(fingerprint or m

模糊C均值聚類以及C實現

1. 基本介紹     同K均值類似,FCM演算法也是一種基於劃分的聚類演算法,它的思想就是使得被劃分到同一簇的物件之間相似度最大,而不同簇之間的相似度最小。     模糊C均值是普通C均值聚類演算法的改進,普通C均值對資料進行硬性劃分,一個樣本一定明確的屬於某一類,FC

MD5加密:此實現不是Windows平臺FIPS驗證的加密演算法的一部分

此實現不是Windows平臺FIPS驗證的加密演算法的一部分 問題描述: 程式中涉及到了MD5加密方法,執行後在某些計算機出現如標題描述之錯誤,情況如下: 解決方案,但不侷限於此一種方式: **按Win+R(或點選開始-執行),並輸入r