MD5&Application In PassWord
来源:互联网 发布:局域网未识别的网络 编辑:程序博客网 时间:2024/06/05 12:16
- MD5 Program
- Analysis
- Code
- MD5hpp
- MD5cpp
- testcpp
- 实验结果截图
- MD5 For Password Protection
- MD5特性
- MD5在密码中的应用
MD5 Program
根据老师的PPT讲解和RFC1321白皮书,我写了一个可执行的MD5加密程序。
Analysis
具体的思想为:
- 先逐个地接收信息字符,然后将每一个字符转化成长度为8位的阿斯克码二进制字符串,然后,加到现有的字符串中,当现有的字符串长度达到512bits时,对它进行处理,然后继续接收下一个512bits长度的字符串,直到最后一个字符输入,然后对最后一段做padding处理,留下最后64位作为长度记录。
- padding的时候有三种情况:现在的长度小于448,长度等于448,长度大于448,然后长度小于448的就直接补到448,长度等于或者大于448的就要补到下一个512分组的448位处,才能够把长度填入。
- 长度的填入是低位存在前32位,高位存在后32位。
- 把每一个512位的分组分成16个32位的无符号整数。之前我们传入的时候是按字符二进制传入的,现在把每四个字符的二进制字符串分为一组,按照小端规则变成16个无符号整数。
- 对每一个512位分组,按照下面的规则做4轮FGHI每轮16次迭代,得出这个分组后的结果:
具体的代码和实验结果如下:
Code
MD5.hpp
#ifndef MD5_HPP#define MD5_HPPclass MD5{public: MD5(); ~MD5(); int SwitchIterationIndex(int i, int j); unsigned int ShiftLeft(unsigned int in, int b); void InitVector(); void InitShiftAmount(); void HMD5(unsigned int* in); void MessageDealing(string s); void PaddingDealing(string s); unsigned int add(unsigned int a, unsigned int b); unsigned int GBCD(int turn, unsigned int b, unsigned int c, unsigned int d); void Print(); void GetXArray(string s);private: unsigned int input[4]; int s[64]; unsigned int x[16]; unsigned long long count;};#endif
MD5.cpp
#include <iostream>#include <iomanip>#include <cmath>#include <cstdlib>#include "MD5.hpp"using namespace std;MD5::MD5() { count = 0; InitVector(); InitShiftAmount();}int MD5::SwitchIterationIndex(int i, int j) { int f; switch (i) { case 0: f = j; break; case 1: f = (1 + 5 * j) % 16; break; case 2: f = (5 + 3 * j) % 16; break; case 3: f = (7 * j) % 16; break; } return f;}unsigned int MD5::ShiftLeft(unsigned int in, int b) { return (unsigned int)(((unsigned long long)in) << b) | (((unsigned long long)in) >> (32 - b));}void MD5::InitVector() { input[0] = 0x67452301; input[1] = 0xEFCDAB89; input[2] = 0x98BADCFE; input[3] = 0x10325476;}void MD5::HMD5(unsigned int* in) { for (int k = 0; k < 4; k++) { for (int q = 0; q < 16; q++) { unsigned int tmps = add(GBCD(k, in[1], in[2], in[3]), in[0]); unsigned int tmp1 = (unsigned int)floor(((unsigned long long)0x100000000)*abs(sin(k * 16 + q+1))); tmps = add(tmps, x[SwitchIterationIndex(k,k*16+q)]); tmps = add(tmps, tmp1); tmp1 = ShiftLeft(tmps, s[k*16+q]); tmps = tmp1 + in[1]; in[0] = in[3]; in[3] = in[2]; in[2] = in[1]; in[1] = tmps; } } input[0] = input[0] + in[0]; input[1] = input[1] + in[1]; input[2] = input[2] + in[2]; input[3] = input[3] + in[3];}void MD5::GetXArray(string s) { string tmp1 = "",tmp2 = "",tmp3 = "",tmp4 = ""; for (int k = 0; k < 16; k++) { tmp1 = s.substr(32 * k, 8); tmp2 = s.substr(32 * k+8, 8); tmp3 = s.substr(32 * k+16, 8); tmp4 = s.substr(32 * k+24, 8); x[k] = strtol(tmp4.c_str(), NULL, 2) << 24; x[k] += strtol(tmp3.c_str(), NULL, 2) << 16; x[k] += strtol(tmp2.c_str(), NULL, 2) << 8; x[k] += strtol(tmp1.c_str(), NULL, 2); }}void MD5::MessageDealing(string s) { count += s.size(); string tmp1 = "",tmp2 = "",tmp3 = "",tmp4 = "", another = ""; if (s.size() < 512) { int a = s.size() % 512; if (a == 448) { s += "1"; for (int i = 1; i < 512; i++) { s += "0"; } another = s.substr(512,448); GetXArray(s); } else if (a < 448) { s += "1"; for (int i = 0; i < (447 - a); i++) { s += "0"; } for (int k = 0; k < 14; k++) { tmp1 = s.substr(32 * k, 8); tmp2 = s.substr(32 * k+8, 8); tmp3 = s.substr(32 * k+16, 8); tmp4 = s.substr(32 * k+24, 8); x[k] = strtol(tmp4.c_str(), NULL, 2) << 24; x[k] += strtol(tmp3.c_str(), NULL, 2) << 16; x[k] += strtol(tmp2.c_str(), NULL, 2) << 8; x[k] += strtol(tmp1.c_str(), NULL, 2); } x[14] =(unsigned int)(count&(unsigned int)0xFFFFFFFF); x[15] = (count>>32); } else { s += "1"; for (int i = 1; i < (960-a); i++) { s += "0"; } another = s.substr(512,448); GetXArray(s); } } else { GetXArray(s); } unsigned int temp[4]; for (int k = 0; k < 4; k++) { temp[k] = input[k]; } HMD5(temp); if (s.size() > 512) PaddingDealing(another);}void MD5::PaddingDealing(string s) { string tmp1 = "",tmp2 = "",tmp3 = "",tmp4 = ""; for (int k = 0; k < 14; k++) { tmp1 = s.substr(32 * k, 8); tmp2 = s.substr(32 * k+8, 8); tmp3 = s.substr(32 * k+16, 8); tmp4 = s.substr(32 * k+24, 8); x[k] = strtol(tmp4.c_str(), NULL, 2) << 24; x[k] += strtol(tmp3.c_str(), NULL, 2) << 16; x[k] += strtol(tmp2.c_str(), NULL, 2) << 8; x[k] += strtol(tmp1.c_str(), NULL, 2); } x[14] =(unsigned int)(count&(unsigned int)0xFFFFFFFF); x[15] = (count>>32); unsigned int temp[4]; for (int k = 0; k < 4; k++) { temp[k] = input[k]; } HMD5(temp);}unsigned int MD5::add(unsigned int a, unsigned int b) { unsigned int c = 0xFFFFFFFF; return (unsigned int)(((unsigned long)a + (unsigned long)b));}unsigned int MD5::GBCD(int turn, unsigned int b, unsigned int c, unsigned int d) { unsigned int f; switch (turn) { case 0: f = ((b)&(c)) | ((~b)&(d)); break; case 1: f = ((b)&(d)) | ((c)&(~d)); break; case 2: f = ((b)^(c) ^ (d)); break; case 3: f = ((c)^ ((b) | (~d))); break; } return f;}void MD5::InitShiftAmount() { s[0] = s[4] = s[8] = s[12] = 7; s[1] = s[5] = s[9] = s[13] = 12; s[2] = s[6] = s[10] = s[14] = 17; s[3] = s[7] = s[11] = s[15] = 22; s[16] = s[20] = s[24] = s[28] = 5; s[17] = s[21] = s[25] = s[29] = 9; s[18] = s[22] = s[26] = s[30] = 14; s[19] = s[23] = s[27] = s[31] = 20; s[32] = s[36] = s[40] = s[44] = 4; s[33] = s[37] = s[41] = s[45] = 11; s[34] = s[38] = s[42] = s[46] = 16; s[35] = s[39] = s[43] = s[47] = 23; s[48] = s[52] = s[56] = s[60] = 6; s[49] = s[53] = s[57] = s[61] = 10; s[50] = s[54] = s[58] = s[62] = 15; s[51] = s[55] = s[59] = s[63] = 21;}void MD5::Print() { unsigned int a = 0, b = 0, c = 0, d = 0; for (int k = 0; k < 4; k++) { a = input[k] & 0xFF; a = a << 24; b = input[k] & 0xFF00; b = b << 8; c = input[k] & 0xFF0000; c = c >> 8; d = input[k] & 0xFF000000; d = d >> 24; input[k] = a + b + c + d; cout<<hex <<setfill('0')<<setw(8)<< input[k]; } cout << endl;}MD5::~MD5() {}
test.cpp
#include "MD5.hpp"using namespace std;string Encode(char c) { int num = (int)c; int temp = 0; string result = ""; for (int i = 7; i >= 0; i--) { temp = num >> i; if (temp % 2 == 0) { result += "0"; } else { result += "1"; } } return result;}int main() { MD5* md = new MD5(); string s = ""; char c; cout << "Please enter the infomation you want to encode and stop by enter ctrl + Z: " << endl; int count = 0; string str = "MD5 for(\""; while (scanf("%c",&c) != EOF) { str += c; if (count == 64) { count = 1; md->MessageDealing(s); s = "" + Encode(c); } else { s += Encode(c); count++; } } if (str.size() != 9) str = str.substr(0,str.size()-1); s =s.substr(0,s.size()-8); md->MessageDealing(s); str += "\"): "; cout << str; md->Print(); delete md; return 0;}
实验结果截图
- Case 1
输入空字符串
结果为d41d8cd98f00b204e9800998ecf8427e - Case 2
输入”a”
结果为:0cc175b9c0f1b6a831c399e269772661 - Case 3
输入”abc”
结果为:900150983cd24fb0d6963f7d28e17f72 - Case 4
输入”message digest”
结果为:f96b697d7cb7938d525a2f31aaf161d0 - Case 5
输入”abcdefghijklmnopqrstuvwxyz”
结果为:c3fcd3d76192e4007dfb496cca67e13b
6.Case 6
输入”ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789”
结果为:d174ab98d277d9f5a5611c2c9f419d9f
7.Case 7
输入”12345678901234567890123456789012345678901234567890123456789012345678901234567890”
结果为:57edf4a22be3c955ac49da2e2107b67a
与RFC321白皮书中提到的example一致:
MD5 For Password Protection
MD5特性
- 因为MD5是把信息转换成一个固定长度的密文,不管明文的长度是多少,密文的长度固定是128位,这样第一点就可以隐藏密码的具体长度。
- 第二个特性就是,MD5是不可逆的,具有单向性,就是说,只有密文,攻击者是无法得知明文的,所以这样来说,密码就比较安全,只有持有者才知道。
- 第三个就是,虽然MD5不是足够安全的,但是很难找到真正不同的两个消息,使得他们的MD5值相同。
MD5在密码中的应用
- 因为密码是检验密码持有者身份的依据,只要verifier知道这个身份是真是假就可以了。所以,verifier(一个公司、网站或其他服务提供商)在将MD5应用于密码校验的时候只需要将密码持有者送来的待校验密码用MD5算法处理,处理后将得到的MD5值与他们数据库中的存储的MD5值进行对比,如果一致,说明验证成功,如果不一致,说明校验失败。最原始的真正的密码在一开始注册的时候就被以MD5的形式存在数据库中。
- 以MD5的形式存在于验证方的数据库中,比裸密码要安全得多,因为攻击者如果得到数据库中的信息,要攻破MD5把原来的密码算出来是很困难的,所以相较之要安全很多。
- 一般的密码其实都可以用MD5加密,用户名也是可以的(或者说,也是很有必要的),只有当用户名和密码同时校验成功才算是校验成功。
阅读全文
0 0
- MD5&Application In PassWord
- about gpdb password md5
- Encrypting Password using md5() function
- mysql password和md5函数
- Password decryption in Weblogic
- LastBit MD5 Password Pro v1.0.533
- locate password in windows 2000
- Enable weak password in Ubuntu
- Login password filters in WinXP
- A group password in Linux
- Display the password in plaintext
- A group password in Linux
- SSLSocket passphrase/password in Python
- Github no password log in
- md5 implementation in java
- MD5 in Actionscript3.0
- forgot root password or reset root password in Debian
- Servlet In Web Application
- [DOTA2地图编辑器记录]
- 快速排序的非递归实现
- stringBuffer和string的区别
- 归并排序
- com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax
- MD5&Application In PassWord
- POJ 2686 Traveling by Stagecoach 笔记
- (三)c#整合zeroIce
- Java的基础字符串的一些方法
- Java API操作Hive
- Gym 100206B Fire station building(三分)
- el表达式的内置对象
- Java设计模式之模板设计模式
- POJ 1523 SPF (割点)