信息安全实验--RSA算法(MFC)
这门课的第二个实验,用MFC实现的,效率较低,上课时没好好听课。。。不知道优化的算法
再加上本来就不感兴趣,后来知道有更好的算法也懒得改了。
用VS2012写的,没vs2012组件直接打开exe的话肯定是各种dll缺少。。.
?
界面:
?
代码依旧是各种混乱,真心不知道怎么写着写着就成这样了。。。
?
?
主要的RSADlg.cpp:
// RSADlg.cpp : 实现文件//#include "stdafx.h"#include "RSA.h"#include "RSADlg.h"#include "afxdialogex.h"#include "CBigInt.h"#ifdef _DEBUG#define new DEBUG_NEW#endifconst CString init_n = TEXT("11118307997040540127125109823105301271848973550332368954427695640548513432576994259450033803985092311988645890908953534205158975851659781290866722576482516739954578771412610881330317110987253909648837");const CString init_e = TEXT("17");const CString init_d = TEXT("6540181174729729486544182248885471336381749147254334679075115082675596136809996623205902237638289590519567442714719605581557953788754188384094731719545461497844638924792771085828281336401032879552233");CBigInt n, e, d;int plainRadio = 2, cipherRadio = 2;// 用于应用程序“关于”菜单项的 CAboutDlg 对话框class CAboutDlg : public CDialogEx{public:CAboutDlg();// 对话框数据enum { IDD = IDD_ABOUTBOX };protected:virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持// 实现protected:DECLARE_MESSAGE_MAP()//virtual BOOL PreCreateWindow(CREATESTRUCT& cs);};CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD){}void CAboutDlg::DoDataExchange(CDataExchange* pDX){CDialogEx::DoDataExchange(pDX);}BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)END_MESSAGE_MAP()// CRSADlg 对话框CRSADlg::CRSADlg(CWnd* pParent /*=NULL*/): CDialogEx(CRSADlg::IDD, pParent)//, plainRadio(0)//, cipherRadio(0){m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);}void CRSADlg::DoDataExchange(CDataExchange* pDX){CDialogEx::DoDataExchange(pDX);// DDX_Radio(pDX, IDC_RADIO_PLAIN_STRING, plainRadio);// DDX_Radio(pDX, IDC_RADIO_CIPHER_STRING, cipherRadio);}BEGIN_MESSAGE_MAP(CRSADlg, CDialogEx)ON_WM_SYSCOMMAND()ON_WM_PAINT()ON_WM_QUERYDRAGICON()ON_BN_CLICKED(ID_CAL_PRIVATE_KEY, &CRSADlg::OnBnClickedCalPrivateKey)ON_BN_CLICKED(IDC_BUTTON_ENCRYPT, &CRSADlg::OnBnClickedButtonEncrypt)ON_BN_CLICKED(IDC_BUTTON_DECRYPT, &CRSADlg::OnBnClickedButtonDecrypt)ON_BN_CLICKED(ID_RANDOM_KEY, &CRSADlg::OnBnClickedRandomKey)ON_BN_CLICKED(ID_CLEARALL, &CRSADlg::OnBnClickedClearall)ON_BN_CLICKED(IDC_RADIO_PLAIN_STRING, &CRSADlg::OnBnClickedRadioPlainString)ON_BN_CLICKED(IDC_RADIO_PLAIN_HEX, &CRSADlg::OnBnClickedRadioPlainHex)ON_BN_CLICKED(IDC_RADIO_PLAIN_DEC, &CRSADlg::OnBnClickedRadioPlainDec)ON_BN_CLICKED(IDC_RADIO_CIPHER_STRING, &CRSADlg::OnBnClickedRadioCipherString)ON_BN_CLICKED(IDC_RADIO_CIPHER_HEX, &CRSADlg::OnBnClickedRadioCipherHex)ON_BN_CLICKED(IDC_RADIO_CIPHER_DEC, &CRSADlg::OnBnClickedRadioCipherDec)END_MESSAGE_MAP()// CRSADlg 消息处理程序BOOL CRSADlg::OnInitDialog(){CDialogEx::OnInitDialog();// 将“关于...”菜单项添加到系统菜单中。// IDM_ABOUTBOX 必须在系统命令范围内。ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);ASSERT(IDM_ABOUTBOX < 0xF000);CMenu* pSysMenu = GetSystemMenu(FALSE);if (pSysMenu != NULL){BOOL bNameValid;CString strAboutMenu;bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);ASSERT(bNameValid);if (!strAboutMenu.IsEmpty()){pSysMenu->AppendMenu(MF_SEPARATOR);pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);}}// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动// 执行此操作SetIcon(m_hIcon, TRUE);// 设置大图标SetIcon(m_hIcon, FALSE);// 设置小图标// TODO: 在此添加额外的初始化代码((CButton *)GetDlgItem(IDC_RADIO_PLAIN_DEC))->SetCheck(TRUE);((CButton *)GetDlgItem(IDC_RADIO_CIPHER_DEC))->SetCheck(TRUE);CheckRadioButton(IDC_RADIO_PLAIN_STRING, IDC_RADIO_PLAIN_HEX, IDC_RADIO_PLAIN_DEC);CheckRadioButton(IDC_RADIO_CIPHER_STRING, IDC_RADIO_CIPHER_HEX, IDC_RADIO_CIPHER_DEC);((CEdit*) GetDlgItem(IDC_EDIT_PRIME_P))->SetWindowText(TEXT("1749216447926182514702512105742818919045636858560222269112115108465858265383133709531890334596655423"));((CEdit*) GetDlgItem(IDC_EDIT_PRIME_Q))->SetWindowText(TEXT("6356164790367747690013998348667958741992268820093032963081503584133406634652288529307215163417754619"));((CEdit*) GetDlgItem(IDC_EDIT_PUBLIC_KEY_PRIME_E))->SetWindowText(init_e);((CEdit*) GetDlgItem(IDC_EDIT_PRIVATE_KEY_PRIME_D))->SetWindowText(init_d);((CEdit*) GetDlgItem(IDC_EDIT_PLAINTEXT))->SetWindowText(TEXT("123456"));n.InPutFromStr(init_n);e.InPutFromStr(init_e);d.InPutFromStr(init_d);srand(unsigned(time(NULL)));//初始化随机数return TRUE; // 除非将焦点设置到控件,否则返回 TRUE}void CRSADlg::OnSysCommand(UINT nID, LPARAM lParam){if ((nID & 0xFFF0) == IDM_ABOUTBOX){CAboutDlg dlgAbout;dlgAbout.DoModal();}else{CDialogEx::OnSysCommand(nID, lParam);}}// 如果向对话框添加最小化按钮,则需要下面的代码// 来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,// 这将由框架自动完成。void CRSADlg::OnPaint(){if (IsIconic()){CPaintDC dc(this); // 用于绘制的设备上下文SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);// 使图标在工作区矩形中居中int cxIcon = GetSystemMetrics(SM_CXICON);int cyIcon = GetSystemMetrics(SM_CYICON);CRect rect;GetClientRect(&rect);int x = (rect.Width() - cxIcon + 1) / 2;int y = (rect.Height() - cyIcon + 1) / 2;// 绘制图标dc.DrawIcon(x, y, m_hIcon);}else{CDialogEx::OnPaint();}}//当用户拖动最小化窗口时系统调用此函数取得光标//显示。HCURSOR CRSADlg::OnQueryDragIcon(){return static_cast<HCURSOR>(m_hIcon);}//手动输入数据void CRSADlg::OnBnClickedCalPrivateKey(){CBigInt n1, p, q, cbi_t, cbi_t2;CString str;char ca[10];((CEdit*) GetDlgItem(IDC_EDIT_PRIME_P))->GetWindowText(str);if (str.GetLength() < 1){MessageBox(TEXT("请输入素数p!"), TEXT("错误"), MB_OK);return;}p = p.InPutFromStr(str);cbi_t.Mov(2);if (cbi_t.Cmp(cbi_t.Mon(p, p)) != 0 && (p.Cmp(2) != 0)){MessageBox(TEXT("输入的p不是素数!"), TEXT("错误"), MB_OK);return;}((CEdit*) GetDlgItem(IDC_EDIT_PRIME_Q))->GetWindowText(str);if (str.GetLength() < 1){MessageBox(TEXT("请输入素数q!"), TEXT("错误"), MB_OK);return;}q = q.InPutFromStr(str);if (cbi_t.Cmp(cbi_t.Mon(q, q)) != 0 && (q.Cmp(2) != 0)){MessageBox(TEXT("输入的q不是素数!"), TEXT("错误"), MB_OK);return;}if (p.Cmp(q) == 0){MessageBox(TEXT("q不能等于p!"), TEXT("错误"), MB_OK);return;}((CEdit*) GetDlgItem(IDC_EDIT_PUBLIC_KEY_PRIME_E))->GetWindowText(str);if (str.GetLength() < 1){MessageBox(TEXT("请输入素数e!"), TEXT("错误"), MB_OK);return;}e.~CBigInt();e = e.InPutFromStr(str);if (cbi_t.Cmp(cbi_t.Mon(e, e)) != 0 && (e.Cmp(2) != 0)){MessageBox(TEXT("输入的e不是素数!"), TEXT("错误"), MB_OK);return;}n.~CBigInt();n.Mov(p);n.Mul(q);n1.Mov(p.Sub(1));n1.Mul(q.Sub(1));if (e.Cmp(n1) != -1){MessageBox(TEXT("素数e要小于φ(n)=(p-1)(q-1)!"), TEXT("错误"), MB_OK);return;}cbi_t2.Mov(e);if (n1.Mon(cbi_t2.Sub(1), e).Cmp(1) != 0){MessageBox(TEXT("素数e和φ(n)=(p-1)(q-1)不互质!"), TEXT("错误"), MB_OK);return;}d.~CBigInt();d = e.Euc(n1);((CEdit*) GetDlgItem(IDC_EDIT_PRIVATE_KEY_PRIME_D))->SetWindowText(d.getResult());((CEdit*) GetDlgItem(IDC_EDIT_PUBLIC_KEY_PRIME_E))->GetWindowText(str);_itoa_s(str.GetLength(), ca, 10);str = ca;((CEdit*) GetDlgItem(IDC_EDIT_KEY_LENGTH))->SetWindowText(str);((CEdit*) GetDlgItem(IDC_EDIT_PRIME_P))->GetWindowText(str);_itoa_s(str.GetLength(), ca, 10);str = ca;((CEdit*) GetDlgItem(IDC_EDIT_PRIME_BITS_P))->SetWindowText(str);((CEdit*) GetDlgItem(IDC_EDIT_PRIME_Q))->GetWindowText(str);_itoa_s(str.GetLength(), ca, 10);str = ca;((CEdit*) GetDlgItem(IDC_EDIT_PRIME_BITS_Q))->SetWindowText(str);}//随机计算密钥void CRSADlg::OnBnClickedRandomKey(){CBigInt n1, p, q, cbi_t, cbi_t2, tmp1, tmp2;CString str;int key_length, prime_bits_p, prime_bits_q, sign;((CEdit*) GetDlgItem(IDC_EDIT_KEY_LENGTH))->GetWindowText(str);key_length = _ttoi(str);//str.Format(TEXT("%d"), key_length);//MessageBox(str, TEXT("结果"), MB_OK);((CEdit*) GetDlgItem(IDC_EDIT_PRIME_BITS_P))->GetWindowText(str);prime_bits_p = _ttoi(str);((CEdit*) GetDlgItem(IDC_EDIT_PRIME_BITS_Q))->GetWindowText(str);prime_bits_q = _ttoi(str);if (key_length < 1 || prime_bits_p < 1 || prime_bits_q < 1){MessageBox(TEXT("请输入公钥长度和随机素数的位数!"), TEXT("错误"), MB_OK);return;}str = random_prime(prime_bits_p);p = p.InPutFromStr(str);cbi_t.Mov(2);while(true){if (cbi_t.Cmp(cbi_t.Mon(p, p)) == 0 || (p.Cmp(2) == 0))break;p.Add(1);if (p.Cmp(pow(10, prime_bits_p)) != -1){str = random_prime(prime_bits_p);p.~CBigInt();p = p.InPutFromStr(str);}}((CEdit*) GetDlgItem(IDC_EDIT_PRIME_P))->SetWindowText(p.getResult());str = random_prime(prime_bits_q);q = q.InPutFromStr(str);cbi_t.Mov(2);while(true){if (cbi_t.Cmp(cbi_t.Mon(q, q)) == 0 || (q.Cmp(2) == 0))if (p.Cmp(q) != 0)break;q.Add(1);if (q.Cmp(pow(10, prime_bits_q)) != -1){str = random_prime(prime_bits_q);q.~CBigInt();q = q.InPutFromStr(str);}}((CEdit*) GetDlgItem(IDC_EDIT_PRIME_Q))->SetWindowText(q.getResult());n.~CBigInt();n.Mov(p);n.Mul(q);n1.Mov(p.Sub(1));n1.Mul(q.Sub(1));str = random_prime(key_length);e.~CBigInt();e = e.InPutFromStr(str);cbi_t.Mov(2);sign = 0;while(true){if (cbi_t.Cmp(cbi_t.Mon(e, e)) == 0 || (e.Cmp(2) == 0)){cbi_t2.Mov(e);if (n1.Mon(cbi_t2.Sub(1), e).Cmp(1) == 0)if (e.Cmp(n) == -1)break;}e.Add(1);if (e.Cmp(pow(10, key_length)) != -1){if (sign = 1000000){((CEdit*) GetDlgItem(IDC_EDIT_PUBLIC_KEY_PRIME_E))->SetWindowText(TEXT(""));((CEdit*) GetDlgItem(IDC_EDIT_PRIVATE_KEY_PRIME_D))->SetWindowText(TEXT(""));MessageBox(TEXT("根据p和q随机计算了e 1000000次还未算出,可能不存在符合条件的素数e,请重新随机计算!"), TEXT("错误"), MB_OK);return;}str = random_prime(key_length);e.~CBigInt();e = e.InPutFromStr(str);sign++;}}((CEdit*) GetDlgItem(IDC_EDIT_PUBLIC_KEY_PRIME_E))->SetWindowText(e.getResult());d.~CBigInt();d = e.Euc(n1);((CEdit*) GetDlgItem(IDC_EDIT_PRIVATE_KEY_PRIME_D))->SetWindowText(d.getResult());}//加密数据void CRSADlg::OnBnClickedButtonEncrypt(){CString str, des;if (d.Cmp(0) == 0){MessageBox(TEXT("请先计算私钥d,否则后果自负。。"), TEXT("严重警告"));return;}((CEdit*) GetDlgItem(IDC_EDIT_PLAINTEXT))->GetWindowText(str);if (str.GetLength() < 1){MessageBox(TEXT("请输入要加密的东东。。。(︶︿︶)"), TEXT("提示"));return;}des = RSAcalculate(str, true);((CEdit*) GetDlgItem(IDC_EDIT_CIPHERTEXT))->SetWindowText(des);}//解密数据void CRSADlg::OnBnClickedButtonDecrypt(){CString str, des;if (d.Cmp(0) == 0){MessageBox(TEXT("请先计算私钥d,否则后果自负。。"), TEXT("严重警告"));return;}((CEdit*) GetDlgItem(IDC_EDIT_CIPHERTEXT))->GetWindowText(str);if (str.GetLength() < 1){MessageBox(TEXT("请输入要解密的东东。。。(︶︿︶)"), TEXT("提示"));return;}des = RSAcalculate(str, false);((CEdit*) GetDlgItem(IDC_EDIT_PLAINTEXT))->SetWindowText(des);}//随机出素数,a为位数CString CRSADlg::random_prime(int a){CString str;int i, t, len = a;//rand();//不加这个,第一位很难改变,原因估计与time有关t = 1+(10-1)*rand()/(RAND_MAX + 1.0);str = (char)(t + 48);for (i = 1; i < a; ++i){t = 10*rand()/(RAND_MAX + 1.0);str += (char)(t + 48);}return str;}//清空所有输入输出void CRSADlg::OnBnClickedClearall(){((CEdit*) GetDlgItem(IDC_EDIT_KEY_LENGTH))->SetWindowText(TEXT(""));((CEdit*) GetDlgItem(IDC_EDIT_PRIME_BITS_P))->SetWindowText(TEXT(""));((CEdit*) GetDlgItem(IDC_EDIT_PRIME_BITS_Q))->SetWindowText(TEXT(""));((CEdit*) GetDlgItem(IDC_EDIT_PRIME_P))->SetWindowText(TEXT(""));((CEdit*) GetDlgItem(IDC_EDIT_PRIME_Q))->SetWindowText(TEXT(""));((CEdit*) GetDlgItem(IDC_EDIT_PUBLIC_KEY_PRIME_E))->SetWindowText(TEXT(""));((CEdit*) GetDlgItem(IDC_EDIT_PRIVATE_KEY_PRIME_D))->SetWindowText(TEXT(""));((CEdit*) GetDlgItem(IDC_EDIT_PLAINTEXT))->SetWindowText(TEXT(""));((CEdit*) GetDlgItem(IDC_EDIT_CIPHERTEXT))->SetWindowText(TEXT(""));n.~CBigInt();e.~CBigInt();d.~CBigInt();}//明文字符串void CRSADlg::OnBnClickedRadioPlainString(){plainRadio = 0;OnBnClickedButtonDecrypt();}//明文16进制void CRSADlg::OnBnClickedRadioPlainHex(){plainRadio = 1;OnBnClickedButtonDecrypt();}//明文10进制void CRSADlg::OnBnClickedRadioPlainDec(){plainRadio = 2;OnBnClickedButtonDecrypt();}//密文字符串void CRSADlg::OnBnClickedRadioCipherString(){cipherRadio = 0;OnBnClickedButtonEncrypt();}//密文16进制void CRSADlg::OnBnClickedRadioCipherHex(){cipherRadio = 1;OnBnClickedButtonEncrypt();}//密文10进制void CRSADlg::OnBnClickedRadioCipherDec(){cipherRadio = 2;OnBnClickedButtonEncrypt();}//将一个16进制字符转为对应的10进制数int CRSADlg::HEXtoDEC(char a){int b;if (a >= 'a' && a <= 'f')b = (int)a - 87;else if (a >= 'A' && a <= 'F')b = (int)a - 55;else if (a >= '0' && a <= '9')b = (int)a - 48;elseb = 0;return b;}//将一个10进制数转为对应的16进制字符char CRSADlg::DECtoHEX(int a){char b;if (a >= 0 && a <= 9)b = a + 48;else if (a >= 10 && a <= 15)b = a + 55;elseb = 0;return b;}//加密,解密的具体实现CString CRSADlg::RSAcalculate(CString str, bool isEncrypt){CString des, s1, s2;CBigInt m, c, tmp;__int64 i, j, a, b, ach, byte2;if (isEncrypt){if (plainRadio == 0 || plainRadio == 1){if (plainRadio == 1){if (!isCorrectFormat(str, 1)){::MessageBox(NULL, TEXT("输入的明文字符串不是十六进制数!!请重新输入!!"), TEXT("错误"), MB_OK);return NULL;}}if (plainRadio == 0){s1 = str;str.Empty();for (j = 0; j < s1.GetLength(); ++j){s2.Format(TEXT("%x"), (int)s1[j]);str += s2;}}a = HEXtoDEC(str[0]);b = HEXtoDEC(str[1]);ach = a*16 + b;m.~CBigInt();m.Mov(ach);for (i = 2; i < str.GetLength(); ++i){m.Mul(16);m.Mul(16);a = HEXtoDEC(str[i]);i++;b = HEXtoDEC(str[i]);ach = a*16 + b;m.Add(ach);}} else if (plainRadio == 2){if (!isCorrectFormat(str, 2)){::MessageBox(NULL, TEXT("输入的明文字符串不是十进制数!!请重新输入!!"), TEXT("错误"), MB_OK);return NULL;}m = m.InPutFromStr(str);}if (m.Cmp(n) == 1){::MessageBox(NULL, TEXT("素数p,q太小,要加密的数据大于n!!\n请重新输入要加密的数据或者更改p和q!"), TEXT("错误"), MB_OK);return NULL;}c = m.Mon(e, n);if (cipherRadio == 0 || cipherRadio == 1) {s1.Empty();s2.Empty();tmp.Mov(c);for (; tmp.Cmp(0) != 0; ){byte2 = tmp.Mod(256);tmp.Div(256);/*_itoa_s(byte2, ca, 10);s2 = ca;MessageBox(s2);*/if (cipherRadio == 0){s1 += (char)byte2;} else {s2.Format(TEXT("%x"), (int)byte2);if (s2.GetLength() == 2){s1 += s2[1];s1 += s2[0];} else {s1 += s2[0];s1 += '0';}s1.MakeUpper();}}str.Empty();for (i = s1.GetLength(); i > 0; --i){str += s1[i-1];s2 = s1[i-1];}} else if (cipherRadio == 2) {str = c.getResult();}//::MessageBox(NULL, str, TEXT(""), MB_OK);return str;} else {if (cipherRadio == 0 || cipherRadio == 1){if (cipherRadio == 1){if (!isCorrectFormat(str, 1)){::MessageBox(NULL, TEXT("输入的密文字符串不是十六进制数!!请重新输入!!"), TEXT("错误"), MB_OK);return NULL;}}if (cipherRadio == 0){s1 = str;str.Empty();for (j = 0; j < s1.GetLength(); ++j){s2.Format(TEXT("%x"), (int)s1[j]);str += s2;}}a = HEXtoDEC(str[0]);b = HEXtoDEC(str[1]);ach = a*16 + b;c.~CBigInt();c.Mov(ach);for (i = 2; i < str.GetLength(); ++i){c.Mul(16);c.Mul(16);a = HEXtoDEC(str[i]);i++;b = HEXtoDEC(str[i]);ach = a*16 + b;c.Add(ach);}} else if (cipherRadio == 2){if (!isCorrectFormat(str, 2)){::MessageBox(NULL, TEXT("输入的密文字符串不是十进制数!!请重新输入!!"), TEXT("错误"), MB_OK);return NULL;}c = c.InPutFromStr(str);}if (c.Cmp(n) == 1){::MessageBox(NULL, TEXT("素数p,q太小,要解密的数据大于n!!\n请重新输入要解密的数据或者更改p和q!"), TEXT("错误"), MB_OK);return NULL;}m = c.Mon(d, n);if (plainRadio == 0 || plainRadio == 1) {s1.Empty();s2.Empty();tmp.Mov(m);for (; tmp.Cmp(0) != 0; ){byte2 = tmp.Mod(256);tmp.Div(256);/*_itoa_s(byte2, ca, 10);s2 = ca;MessageBox(s2);*/if (plainRadio == 0){s1 += (char)byte2;} else {s2.Format(TEXT("%x"), (int)byte2);if (s2.GetLength() == 2){s1 += s2[1];s1 += s2[0];} else {s1 += s2[0];s1 += '0';}s1.MakeUpper();}}str.Empty();for (i = s1.GetLength(); i > 0; --i){str += s1[i-1];s2 = s1[i-1];}} else if (plainRadio == 2) {str = m.getResult();}return str;}}//判断字符串是否符合指定格式bool CRSADlg::isCorrectFormat(CString str, int form){if (form == 1)return (str == str.SpanIncluding(TEXT("0123456789ABCDEFabcdef")));else if (form == 2)return (str == str.SpanIncluding(TEXT("0123456789")));return false;}
?