②P计算r=(gkmodp)modq和s=(k-1(H(m)+xr))modq
签名结果是(m,r,s)。
③验证时
计算w=s-1modq
计算u1=(H(m)*w)modq
计算u2=(r*w)modq
计算v=((gu1*yu2)modp)modq
若v=r,则认为签名有效。
5.结果
在VC++编译环境下,可实现对DSA数字签名。
其中对摘要的加密和签名可以选择不同的算法。
结果如图:
6.结论
DSA主要依赖于整数有限域离散对数难题。
素数P必须足够大,且p-1至少包含一个大素数因子以抵抗Pohlig&Hellman算法的攻击。
M一般都应采用信息的HASH值(官方推荐为SHA算法)。
DSA的安全性主要依赖于p和g,若选取不当则签名容易伪造,应保证g对于p-1的大素数因子不可约。
DSA的安全性要次于ECC与RSA不相上下。
但是有一点,就是DSA算法的验证过程R,S是以明文形式出现的,这点很容易被利用。
但是随着加密技术的发展,椭圆曲线数字签名算法(ECDSA)是使用椭圆曲线对数字签名算法(DSA)的模拟。
与普通的离散对数问题(discretelogarithmproblemDLP)和大数分解问题(integerfactorizationproblemIFP)不同,椭圆曲线离散对数问题(ellipticcurvediscretelogarithmproblemECDLP)没有亚指数时间的解决方法。
因此椭圆曲线密码的单位比特强度要高于其他公钥体制。
7.附录
//数字签名Dlg.cpp:
implementationfile
//
#include"stdafx.h"
#include"数字签名.h"
#include"数字签名Dlg.h"
#include"BigInt.h"
#include"MD5.h"
#include"SHA1.h"
#ifdef_DEBUG
#definenewDEBUG_NEW
#undefTHIS_FILE
staticcharTHIS_FILE[]=__FILE__;
#endif
CBigIntsha(CBigInty);
CBigIntpow2(constintx,inty);
CBigIntmakerandnumber(unsignedintlen);
CBigIntpow3(CBigIntx,CBigInty,CBigIntm);
/////////////////////////////////////////////////////////////////////////////
//CAboutDlgdialogusedforAppAbout
classCAboutDlg:
publicCDialog
{
public:
CAboutDlg();
//DialogData
//{{AFX_DATA(CAboutDlg)
enum{IDD=IDD_ABOUTBOX};
//}}AFX_DATA
//ClassWizardgeneratedvirtualfunctionoverrides
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtualvoidDoDataExchange(CDataExchange*pDX);//DDX/DDVsupport
//}}AFX_VIRTUAL
//Implementation
protected:
//{{AFX_MSG(CAboutDlg)
virtualvoidOnOK();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
CAboutDlg:
:
CAboutDlg():
CDialog(CAboutDlg:
:
IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}
voidCAboutDlg:
:
DoDataExchange(CDataExchange*pDX)
{
CDialog:
:
DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CAboutDlg,CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
//DMyDlgdialog
DMyDlg:
:
DMyDlg(CWnd*pParent/*=NULL*/)
:
CDialog(DMyDlg:
:
IDD,pParent)
{
//{{AFX_DATA_INIT(DMyDlg)
m_P=_T("");
m_Q=_T("");
m_G=_T("");//mpdifiedin2007.6.10
m_Y=_T("");
m_S=_T("");
m_V=_T("");
m_Len=0;
m_OUT=_T("");
m_IN=_T("");
ready=0;
m_file=_T("");
m_string=_T("");
//}}AFX_DATA_INIT
//NotethatLoadIcondoesnotrequireasubsequentDestroyIconinWin32
m_hIcon=AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
voidDMyDlg:
:
DoDataExchange(CDataExchange*pDX)
{
CDialog:
:
DoDataExchange(pDX);
//{{AFX_DATA_MAP(DMyDlg)
DDX_Text(pDX,IDC_P,m_P);
DDX_Text(pDX,IDC_Q,m_Q);
DDX_Text(pDX,IDC_G,m_G);//mpdifiedin2007.6.10
DDX_Text(pDX,IDC_Y,m_Y);
DDX_Text(pDX,IDC_S,m_S);
DDX_Text(pDX,IDC_V,m_V);
DDX_CBIndex(pDX,IDC_COMBO,m_Len);
DDX_Text(pDX,IDC_OUTPUT,m_OUT);
DDX_Text(pDX,IDC_INPUT,m_IN);
DDX_Text(pDX,IDC_EDITFILE,m_file);
DDX_Text(pDX,IDC_STRING,m_string);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(DMyDlg,CDialog)
//{{AFX_MSG_MAP(DMyDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BUTTON_GET,OnButtonGet)
ON_BN_CLICKED(IDC_ENCRYPT,OnEncrypt)
ON_BN_CLICKED(IDC_DECRYPT,OnDecrypt)
ON_BN_CLICKED(IDC_Btnfile,OnBtnfile)
ON_EN_CHANGE(IDC_EDITFILE,OnChangeEditfile)
ON_EN_CHANGE(IDC_STRING,OnChangeString)
ON_BN_CLICKED(IDC_SHA1_RADIO,OnSha1Radio)
ON_BN_CLICKED(IDC_MD5_RADIO,OnMd5Radio)
ON_CBN_EDITCHANGE(IDC_COMBO,OnEditchangeCombo)
ON_BN_CLICKED(IDC_BUTTON1,OnButton1)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
//DMyDlgmessagehandlers
BOOLDMyDlg:
:
OnInitDialog()
{
CDialog:
:
OnInitDialog();
//Add"About..."menuitemtosystemmenu.
//IDM_ABOUTBOXmustbeinthesystemcommandrange.
ASSERT((IDM_ABOUTBOX&0xFFF0)==IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX<0xF000);
CMenu*pSysMenu=GetSystemMenu(FALSE);
if(pSysMenu!
=NULL)
{
CStringstrAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if(!
strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING,IDM_ABOUTBOX,strAboutMenu);
}
}
//Settheiconforthisdialog.Theframeworkdoesthisautomatically
//whentheapplication'smainwindowisnotadialog
SetIcon(m_hIcon,TRUE);//Setbigicon
SetIcon(m_hIcon,FALSE);//Setsmallicon
//TODO:
Addextrainitializationhere
CheckRadioButton(IDC_MD5_RADIO,IDC_SHA1_RADIO,IDC_MD5_RADIO);
UpdateData(FALSE);
returnTRUE;//returnTRUEunlessyousetthefocustoacontrol
}
voidDMyDlg:
:
OnSysCommand(UINTnID,LPARAMlParam)
{
if((nID&0xFFF0)==IDM_ABOUTBOX)
{
CAboutDlgdlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog:
:
OnSysCommand(nID,lParam);
}
}
//Ifyouaddaminimizebuttontoyourdialog,youwillneedthecodebelow
//todrawtheicon.ForMFCapplicationsusingthedocument/viewmodel,
//thisisautomaticallydoneforyoubytheframework.
voidDMyDlg:
:
OnPaint()
{
if(IsIconic())
{
CPaintDCdc(this);//devicecontextforpainting
SendMessage(WM_ICONERASEBKGND,(WPARAM)dc.GetSafeHdc(),0);
//Centericoninclientrectangle
intcxIcon=GetSystemMetrics(SM_CXICON);
intcyIcon=GetSystemMetrics(SM_CYICON);
CRectrect;
GetClientRect(&rect);
intx=(rect.Width()-cxIcon+1)/2;
inty=(rect.Height()-cyIcon+1)/2;
//Drawtheicon
dc.DrawIcon(x,y,m_hIcon);
}
else
{
CDialog:
:
OnPaint();
}
}
//Thesystemcallsthistoobtainthecursortodisplaywhiletheuserdrags
//theminimizedwindow.
HCURSORDMyDlg:
:
OnQueryDragIcon()
{
return(HCURSOR)m_hIcon;
}
voidDMyDlg:
:
OnButtonGet()
{
//TODO:
Addyourcontrolnotificationhandlercodehere
ready=1;
UpdateData(TRUE);
CTimet0=CTime:
:
GetCurrentTime();
/*
intlen=8;//intlen=2;modifiedin20076.9
for(inti=0;iP.Mov(0);
Q.Mov(0);
N.Mov(0);
E.Mov(0);
P.GetPrime(len);
Q.GetPrime(len);
N.Mov(P.Mul(Q));
N.Put(m_P);
P.m_ulValue[0]--;
Q.m_ulValue[0]--;
P.Mov(P.Mul(Q));
D.Mov(0x10001);//mpdifiedin2007.6.10
//m_D="10001";//mpdifiedin2007.6.10
E.Mov(D.Euc(P));
E.Put(m_Q);
CTimet1=CTime:
:
GetCurrentTime();
CTimeSpant=t1-t0;
m_OUT.Format("%d",t.GetTotalSeconds());
m_OUT+="秒";
Q.m_ulValue[0]=0;
*/
CBigIntr,s,u,v[4],w,p,q,t;//,H,G,X,Y;
intn=3,b=31,L=512,g=160,T=1;
t.Mov(pow2(2,g));
while(T)
{
s.Mov(makerandnumber(g));
//r.Mov(s);
//r.Mov(r.Add
(1));
//r.Mov(r.Mod(t));
//u.Mov(sha(s));
q.Mov(sha(s));
q.m_ulValue[0]=q.m_ulValue[0]|0x1;
q.m_ulValue[4]=q.m_ulValue[4]|0x80000000;
while(q.Rab()==0)
q.Mov(q.Add
(2));
intC=0,N=2;
for(intk=0;k<4;k++)
{
v[k].Mov(s);
v[k].Mov(v[k].Add(N+k));
v[k].Mov(v[k].Mod(t));
v[k].Mov(sha(v[