㈠ 如何利用OpenSSL库进行RSA加密和解密

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<openssl/rsa.h>
#include<openssl/engine.h>

intmain(intargc,char*argv[])
{
printf("openssl_testbegin ");
RSA*rsa=NULL;
charoriginstr[]="hello ";//这是我们需要加密的原始数据
//allocateRSAstructure,首先需要申请一个RSA结构题用于存放生成的公私钥,这里rsa就是这个结构体的指针
rsa=RSA_new();
if(rsa==NULL)
{
printf("RSA_newfailed ");
return-1;
}

//generateRSAkeys
BIGNUM*exponent;
exponent=BN_new();//生成RSA公私钥之前需要选择一个奇数(oddnumber)来用于生成公私钥
if(exponent==NULL)
{
printf("BN_newfailed ");
gotoFAIL1;
}
if(0==BN_set_word(exponent,65537))//这里选择奇数65537
{
printf("BN_set_wordfailed ");
gotoFAIL1;
}


//这里molus的长度选择4096,小于1024的molus长度都是不安全的,容易被破解
if(0==RSA_generate_key_ex(rsa,4096,exponent,NULL))
{
printf("RSA_generate_key_exfailed ");
gotoFAIL;
}
char*cipherstr=NULL;
//分配一段空间用于存储加密后的数据,这个空间的大小由RSA_size函数根据rsa算出
cipherstr=malloc(RSA_size(rsa));
if(cipherstr==NULL)
{
printf("malloccipherstrbuffailed ");
gotoFAIL1;
}
//下面是实际的加密过程,最后一个参数paddingtype,有以下几种。
/*
RSA_PKCS1_PADDINGPKCS#1v1.5padding..
RSA_PKCS1_OAEP_PADDING
EME-OAEPasdefinedinPKCS#1v2.0withSHA-1,..
RSA_SSLV23_PADDING
PKCS#1v1.5paddingwithanSSL-.
RSA_NO_PADDING
RawRSAencryption.ntheapplicationcode..
*/
//这里首先用公钥进行加密,选择了RSA_PKCS1_PADDING

if(RSA_size(rsa)!=RSA_public_encrypt(strlen(originstr)+1,originstr,cipherstr,rsa,RSA_PKCS1_PADDING))
{
printf("encryptionfailure ");
gotoFAIL2;
}
printf("theoriginalstringis%s ",originstr);
printf("theencryptedstringis%s ",cipherstr);


//Now,let'
//下面来用私钥解密,首先需要一个buffer用于存储解密后的数据,这个buffer的长度要足够(小于RSA_size(rsa))
//这里分配一个长度为250的字符数组,应该是够用的。
chardecrypted_str[250];
intdecrypted_len;
if(-1=(decrypted_len=RSA_private_decrypt(256,cipherstr,decrypted_str,rsa,RSA_PKCS1_PADDING)))
{
printf("decryptionfailure ");
gotoFAIL2;
}
printf("decryptedstringlengthis%d,decryped_stris%s ",decrypted_len,decrypted_str);
FAIL2:
free(cipherstr);
FAIL1:
BN_free(exponent);
FAIL:
RSA_free(rsa);
return0;
}

以上是源代码,下面使用下面的编译命令在源码所在路径下生成可执行文件
gcc *.c -o openssl_test -lcrypto -ldl -L/usr/local/ssl/lib -I/usr/local/ssl/include
其中,-lcrypto和-ldl是必须的,前者是OpenSSL中的加密算法库,后者是用于成功加载动态库。

㈡ 设计一个简单的数据加密算法

// ecfileDlg.cpp : implementation file
//

#include "stdafx.h"
#include "ecfile.h"
#include "ecfileDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:
CAboutDlg();

// Dialog Data
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
//}}AFX_DATA

// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL

// Implementation
protected:
//{{AFX_MSG(CAboutDlg)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
// No message handlers
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CEcfileDlg dialog

CEcfileDlg::CEcfileDlg(CWnd* pParent /*=NULL*/)
: CDialog(CEcfileDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CEcfileDlg)
m_path = _T("");
m_pass = _T("");
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CEcfileDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CEcfileDlg)
DDX_Text(pDX, IDC_PASSWORD, m_path);
DDX_Text(pDX, IDC_PASS1, m_pass);
//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CEcfileDlg, CDialog)
//{{AFX_MSG_MAP(CEcfileDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_E, OnE)
ON_BN_CLICKED(IDC_D, OnD)
ON_BN_CLICKED(IDC_BROW, OnBrow)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

BOOL CEcfileDlg::OnInitDialog()
{
CDialog::OnInitDialog();

ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);

CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}

SetIcon(m_hIcon, TRUE);
SetIcon(m_hIcon, FALSE);

return TRUE;
}

void CEcfileDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}

void CEcfileDlg::OnPaint()
{
CDialog::OnPaint();
}

HCURSOR CEcfileDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}

void CEcfileDlg::OnE()
{
UpdateData(TRUE);
if(m_path == "")
{
AfxMessageBox("怎么没有选择要加密的文件就开始加密啊?");
return;
}

UpdateData(TRUE);
if(m_pass == "")
{
AfxMessageBox("没有写上密码");
return;
}

if(ecfile(m_path))
{
MessageBox("加密成功了已经");
}
else
{
MessageBox("没加密成功");
}
}

void CEcfileDlg::OnD()
{
UpdateData(TRUE);
if(m_path == "")
{
AfxMessageBox("怎么没有选择要加密的文件就开始解密啊?");
return;
}

UpdateData(TRUE);
if(m_pass == "")
{
AfxMessageBox("没有写上密码");
return;
}

if(dcfile(m_path))
{
MessageBox("解密成功了");
}
else
{
MessageBox("解密失败了");
}
}

void CEcfileDlg::OnBrow()
{
CFileDialog dlg(TRUE);
if(dlg.DoModal() == IDOK)
{
m_path = dlg.GetPathName();
UpdateData(FALSE);
}
else
{
return;
}
}

//给文件加密的函数
BOOL CEcfileDlg::ecfile(LPCTSTR fpath)
{
char *data;
CFile *file;
DWORD flen;

m_password = epass();

file = new CFile;
if ( !file->Open(fpath, CFile::shareDenyNone|CFile::modeReadWrite))
{
return FALSE;
}

flen = file->GetLength();
data = new char[(int)flen];

file->SeekToBegin();
file->Read(data, flen);

for(int i=0; i<(int)flen; i++)
{
data[i] ^= m_password;
data[i] ^= flen;
}

file->SeekToBegin();
file->Write(data, flen);
delete[] data;

//添加密码验证信息
char cpass[5] = "love";
for(int j=0; j<5; j++)
{
cpass[j] ^= m_password;
}
file->SeekToEnd();
file->Write(&cpass, 5);
file->Close();
delete file;

return TRUE;
}

//给文件解密的函数
BOOL CEcfileDlg::dcfile(LPCTSTR fpath)
{
char *data;
CFile *file;
DWORD flen;
char love[5];

file = new CFile;
if( !file->Open(fpath, CFile::shareDenyNone|CFile::modeReadWrite))
{
return FALSE;
}

flen = file->GetLength();
data = new char[(int)flen];

//检验密码是不是正确
file->Seek(-5, CFile::end);
file->Read(&love, 5);

m_password = epass();

for(int i=0; i<5; i++)
{
love[i] ^= m_password;
}

if(strcmp(love, "love")!=0)
{
return FALSE;
}

//解密
file->SeekToBegin();
file->Read(data, flen);

for(int j=0; j<(int)flen; j++)
{
data[j] ^= m_password;
data[j] ^= (flen-5);
}
file->SeekToBegin();
file->Write(data, flen);
file->SetLength(flen-5);
file->Close();

delete[] data;
delete file;
return TRUE;
}

//获得密码的函数
__int64 CEcfileDlg::epass()
{
DWORD plen;
char *ppass;
__int64 mc= 8757735233305;
UpdateData(TRUE);

ppass = m_pass.GetBuffer(0);

plen = strlen(ppass);

for(int i=0; i<(int)plen; i++)
{
mc ^= ppass[i]|128;
}
return mc;
}

㈢ java 字母移位加密

【可加密,也可解密(-key)】

public class Wangyf {

public static void main(String[] args) {
String str = "i am student zzzZZZ";

//加密
String str2 = getString( str, 1 );
System.out.println(str2);

//解密 用 -KEY
System.out.println(getString( str2, -1));
}

private static final char C1 = 'a';
private static final char C2 = 'z';
private static final char C3 = 'A';
private static final char C4 = 'Z';

public static String getString(String str, int key) {
key %= 26;
if(key == 0 ){
return str;
}
char[] chars = str.toCharArray();
for(int i = chars.length - 1 ; i >= 0 ; i --){
if(chars[i] >= C3 && chars[i] <= C4){
chars[i] += key;
if(chars[i] > C4){
chars[i] = (char) ( chars[i] -C4 + C3 - 1);
}else if(chars[i] < C3){
chars[i] = (char) (C4 - (C3 -chars[i]) + 1);
}
} else if(chars[i] >= C1 && chars[i] <= C2){
chars[i] += key;
if(chars[i] > C2){
chars[i] = (char) ( chars[i] - C2 + C1 - 1);
}else if(chars[i] < C1){
chars[i] = (char) (C2 - (C1 - chars[i]) + 1);
}
}
}
return new String( chars );
}

}

【测试结果】

j bn tuvefou aaaAAA
i am student zzzZZZ