信息安全实验--RSA算法(MFC)
程序员文章站
2022-04-09 10:50:57
...
这门课的第二个实验,用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 #endif const 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; else b = 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; else b = 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; }