RSA实验报告

时间:2019-05-14 02:08:02下载本文作者:会员上传
简介:写写帮文库小编为你整理了多篇相关的《RSA实验报告》,但愿对你工作学习有帮助,当然你在写写帮文库还可以找到更多《RSA实验报告》。

第一篇:RSA实验报告

一 实验目的

1.了解非对称加密机制 2.理解RSA算法的加解密原理

3.熟悉Java的学习以及运用Java实现RSA算法的加解密过程

二 实验背景

在公开密钥密码体制中,加密密钥(即公开密钥)PK是公开信息,而解密密钥(即秘密密钥)SK是需要保密的。加密算法E和解密算法D也都是公开的。虽然秘密密钥SK是由公开密钥PK决定的,但却不能根据PK计算出SK。正是基于这种理论,1978年出现了著名的RSA算法,它通常是先生成一对RSA 密钥,其中之一是保密密钥,由用户保存;另一个为公开密钥,可对外公开,甚至可在网络服务器中注册。为提高保密强度,RSA密钥至少为500位长,一般推荐使用1024位。这就使加密的计算量很大。为减少计算量,在传送信息时,常采用传统加密方法与公开密钥加密方法相结合的方式,即信息采用改进的DES或IDEA对话密钥加密,然后使用RSA密钥加密对话密钥和信息摘要。对方收到信息后,用不同的密钥解密并可核对信息摘要。

RSA算法是第一个能同时用于加密和数字签名的算法,也易于理解和操作。RSA是被研究得最广泛的公钥算法,从提出到现在的这么多年里,经历了各种攻击的考验,逐渐为人们接受,普遍认为是目前最优秀的公钥方案之一。

三 实验原理

1.非对称密钥加解密概述

使用对称密钥加密体制进行保密通信时,任意不同的两个用户之间都应该使用互不相同的密钥。这样,如果一个网络中有n个用户,他们之间彼此都可能进行秘密通信,这时网络中将需要n(n-1)/2个密钥(其中,每个用户都需要保存n-1个密钥),这样巨大的密钥量给密钥分配和管理带来了极大的困难。另外,随着计算机网络,特别是因特网的发展,网络上互不相识的用户可能需要进行保密的会话(例如,如果用户在进行电子商务活动时,需要保密的连接,这时的客户对象可能根本不是固定的对象)。最后,对称密钥加密机制难以解决签名验证问题。

非对称密钥加密也称为公开密钥加密,或者叫做公钥加密算法。使用公开密钥密码的每一个用户都分别拥有两个密钥:加密密钥和解密密钥,它们两者并不相同,并且由加密密钥得到解密密钥在计算机上是不可行的。每一个用户的加密密钥都是公开的。因此,加密密钥也称为公开密钥。所有用户的公开密钥都将记录在作用类似于电话号码薄的密钥本上,而它可以被所有用户访问,这样每一个用户都可以得到其他所有用户的公开密钥。同时,每一个用户的解密密钥将由用户保存并严格保密。因此,解密密钥也称为私有密钥。

非对称密码算法解决了对称密码体制中密钥管理的难题,并提供了对信息发送人的身份进行验证的手段,是现代密码学最重要的发明。公钥加密算法一般是将对密钥的求解转化为对数学上的困难问题的求解,例如RSA算法的安全性是建立在“大数分解和素性检测”这个数论难题的基础上,已知两个大素数a和b,求出a*b是容易计算的,而已知a*b,想知道其是哪两个大素数的乘积目前还没有好的计算方法,另外也有一些非对称加密算法(如ELGamal算法)的安全性是基于求“离散对数”这个数学难题上的。

在公钥密码系统中每个实体都有自己的公钥和相应的私钥。公钥密码系统的加密变换和解密变换分别用E和D表示。任何实体B要向实体A发送信息m的步骤如下:实体B首先获得实体A的真实公钥的拷贝(eA),实体B使用eA计算密文c=E(m)并发送给实体A,实体A使用自己的私钥dA,计算m=D(c)解密密文,恢复出明文m。这里公钥不需要保密,但要保证它的真实性,即eA确实是实体A掌握的私钥dA所对应的公钥。提供真实的公钥比安全地分配密钥实现起来要容易得多。这也是公钥密码系统的主要优点之一。

公钥密码系统的主要目的是提供保密性,它不能提供数据源认证(data origin authentication)和数据完整性(data integrity)。数据源认证是指:指定的数据是在以前的某个时间确实是由真正的源创建的。数据完整性是指:真正的源创建该数据后经过传输后存储没有发生改变。数据源认证和数据完整性要由其他技术来提供(如消息认证码技术、数字签名技术等)。

从本质上来看,公钥密码比对称密钥密码加密的速度要慢,粗略的说,公钥加密算法RSA硬件实现比分组加密算法DES硬件实现的速度慢1500倍,而软件实现的速度要慢100倍。

公钥解密也可以提供认证保证(如:在实体认证协议、带认证的密钥建立协议等)。公钥加密中必须有颁发让发送消息的人得到想要发送到的那个人的公钥的真实拷贝,否则就会受到伪装攻击。在实践中有很多方法分发真实的公钥,如:使用可信的公共文件,使用在线可信服务器,使用离线服务器和认证。

2.公钥加解密的优缺点:

1)大型网络中的每个用户需要的密钥数量少。

2)对管理公钥的可信第三方的信任程度要求不高而且是离线的。3)只有私钥是保密的,而公钥只要保证它的真实性。4)多数公钥加密比对称密钥加密的速度要慢几个数量级。5)公钥加密方案的密钥长度比对称加密的密钥要长。6)公钥加密方案没有被证明是安全的。

公钥密码的概念本身就被公认为是密码学上的一块里程碑。三十多年来的研究表明,公钥密码成功地解决了计算机网络安全中的密钥管理,身份认证和数字签名等问题,已经成为信息安全技术中的重大核心技术。

四 RSA算法

1.概述

RSA加密算法于1977年由美国麻省理工学院的Ronal Rivest,Adi Shamir和Len Adleman三位年轻教授提出,并以三人的姓氏Rivest,Shamir和Adleman命名为RSA算法。这三位科学家荣获2002年度图灵奖,以表彰他们在算法方面的突出贡献。该算法利用了数论领域的一个事实,那就是虽然把两个大质数相乘生成一个合数是件十分容易的事情,但要把一个合数分解为两个质数的乘积却十分困难。合数分解问题目前仍然是数学领域尚未解决的一大难题,至今没有任何高效的分解方法。它无须收发双方同时参与加密过程,既可以用于保密也可以用于签名,因而非常适合于电子邮件系统的加密,互连网和信用卡安全系统。

算法概述:找两素数p和q,取n=p*q,取t=(p-1)*(q-1),取任何一个数e,要求满足e

2.算法设计

1)public static void GetPrime()说明:利用Java语言的中的java.math.BigInteger类的方法中随机产生大数。2)public static boolean MillerRobin(BigInteger num)参数说明:num是由GetPrime方法产生的大数。

说明:这个方法判断GetPrime方法传过来的是否是一个素数,是就返回true,否就返回false。

3)public static BigInteger powmod(BigIntegera,BigIntegert,BigInteger num)说明:这个方法对传入的大数进行幂运算。

4)public static BigInteger invmod(BigInteger a,BigInteger b)说明:这个方法对大数进行取模运算。

5)public static String Encode(String inStr,BigInteger PrimeP,BigInteger PrimeQ,BigInteger n,int nLen,int m,JTextField d)方法名称:加密算法。

参数说明:

inStr是从界面输入的明文。

PrimeP和PrimeQ是由GetPrime方法产生的两个大素数。n是由PrimeP和PrimeQ得到的值。nLen为n的长度。

d为公钥。

6)public static String Decode(String inStr,BigInteger PrimeP,BigInteger PrimeQ,BigInteger n,int nLen,int m,JTextField e)方法名称:解密算法。参数说明:

inStr是从界面输入的明文。

PrimeP和PrimeQ是由GetPrime方法产生的两个大素数。n是由PrimeP和PrimeQ得到的值。nLen为n的长度。e为私钥。

在对称加密中:n,d两个数构成公钥,可以告诉别人;n,e两个数构成私钥,e自己保留,不让任何人知道。给别人发送的信息使用e加密,只要别人能用d解开就证明信息是由你发送的,构成了签名机制。别人给你发送信息时使用d加密,这样只有拥有e的你能够对其解密。

RSA的安全性在于对于一个大数n,没有有效的方法能够将其分解从而在已知n,d的情况下无法获得e;同样在已知n,e的情况下无法求得d。五 实验源代码

import javax.swing.*;

import java.awt.event.*;

import java.math.*;

import java.util.*;

import java.awt.*;

import java.io.*;

public class RSA1{

public static void main(String[] args)

{

MyFrame frame = new MyFrame();

MyPanel_fbutton panel_fbutton MyPanel_fbutton(frame,frame.P,frame.Q,frame.d,frame.e);

FlowLayout fl = new FlowLayout(FlowLayout.CENTER,0,0);

frame.setLayout(fl);

frame.add(panel_fbutton);

frame.setBounds(150, 100, 500, 480);

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

frame.setVisible(true);

}

}

class MyFrame extends JFrame

{

public MyFrame()

{

setTitle(“RSA算法”);

add(wel);

MyPanel_p panel_p = new MyPanel_p(P);

add(panel_p);

MyPanel_q panel_q = new MyPanel_q(Q);

add(panel_q);

MyPanel_d panel_d = new MyPanel_d(d);

add(panel_d);

MyPanel_e panel_e = new MyPanel_e(e);

add(panel_e);

MyPanel_in panel_in = new MyPanel_in(input);

add(panel_in);

MyPanel_out panel_out = new MyPanel_out(output);

add(panel_out);

=

new

MyPanel_out1 panel_out1 = new MyPanel_out1(output1);

add(panel_out1);

MyPanel_button panel_button = new MyPanel_button(P,Q,d,e,input,output,output1);

add(panel_button);

}

private JLabel wel = new JLabel(“

RSA算法演示

”);

protected JTextField P = new JTextField(35);

protected JTextField Q = new JTextField(35);

protected JTextField d = new JTextField(35);

protected JTextField e = new JTextField(35);

protected JTextArea input = new JTextArea(4,35);

protected JTextArea output = new JTextArea(4,35);

protected JTextArea output1 = new JTextArea(4,35);

}

class MyPanel_fbutton extends JPanel

{

public MyPanel_fbutton(Frame aframe,JTextField aP, JTextField aQ, JTextField ad, JTextField ae)

{

frame = aframe;

P = aP;

Q = aQ;

e = ae;

d = ad;

}

private Frame frame;

private JTextField P;

private JTextField Q;

private JTextField d;

private JTextField e;

}

class MyPanel_p extends JPanel

{

public MyPanel_p(JTextField aP)

{

P=aP;

add(new JLabel(“

质数 P:”));

add(P);

}

private JTextField P;

}

class MyPanel_q extends JPanel

{

public MyPanel_q(JTextField aQ)

{

Q=aQ;

add(new JLabel(“

质数 Q:”));

add(Q);

}

private JTextField Q;

}

class MyPanel_d extends JPanel

{

public MyPanel_d(JTextField ad)

{

d=ad;

add(new JLabel(“

钥:”));

add(d);

}

private JTextField d;

}

class MyPanel_e extends JPanel

{

public MyPanel_e(JTextField ae)

{

e=ae;

add(new JLabel(“

钥:”));

add(e);

}

private JTextField e;

}

class MyPanel_in extends JPanel

{

public MyPanel_in(JTextArea ainput)

{

input = ainput;

add(new JLabel(“

输入明文:”));

JScrollPane jsp1 = new JScrollPane(input,v,h);

add(jsp1);

}

private JTextArea input;

int v=JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED;

int h=JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED;

}

class MyPanel_out extends JPanel

{

public MyPanel_out(JTextArea aoutput)

{

output = aoutput;

add(new JLabel(“

生成的密文:”));

JScrollPane jsp = new JScrollPane(output,v,h);

add(jsp);

}

private JTextArea output;

int v=JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED;

int h=JScrollPane.HORIZONTAL_SCROLLBAR_NEVER;

}

class MyPanel_out1 extends JPanel

{

public MyPanel_out1(JTextArea aoutput1)

{

output1 = aoutput1;

add(new JLabel(“解密后的明文:”));

JScrollPane jsp = new JScrollPane(output1,v,h);

add(jsp);

}

private JTextArea output1;

int v=JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED;

int h=JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED;

}

class MyPanel_button extends JPanel

{

public MyPanel_button(JTextField aP,JTextField aQ,JTextField ad,JTextField ae,JTextArea ainput,JTextArea aoutput,JTextArea aoutput1)

{

P = aP;

Q = aQ;

e = ae;

d = ad;

input = ainput;

output = aoutput;

output1 = aoutput1;

randProduce.addActionListener(new RandListener(P, Q));

add(randProduce);

randD.addActionListener(new RandDListener(P, Q, d, e));

add(randD);

encode.addActionListener(new EncodeListener(P, Q, d, e, input, output));

add(encode);

decode.addActionListener(new DecodeListener(P, Q, d, e, output, output1));

add(decode);

}

private JTextField P;

private JTextField Q;

private JTextField d;

private JTextField e;

private JTextArea input;

private JTextArea output;

private JTextArea output1;

private JButton randProduce = new JButton(“生成质数P和Q”);

private JButton randD = new JButton(“生成公钥和私钥”);

private JButton encode = new JButton(“加密”);

private JButton decode = new JButton(“解密”);

}

class FileEncodeListener implements ActionListener

{

public FileEncodeListener(Frame f,JTextField ap, JTextField aq,JTextField ae,JTextField ad)

{

P = ap;

Q = aq;

E = ae;

D = ad;

fr = f;

}

public void actionPerformed(ActionEvent ee)

{

FileDialog fd = new FileDialog(fr);

fd.setVisible(true);

String infileName =fd.getDirectory()+fd.getFile();

String inStr = new String();

inStr = PublicMethod.read(infileName);

BigInteger PrimeP = new BigInteger(P.getText());

BigInteger PrimeQ = new BigInteger(Q.getText());

BigInteger n =PrimeP.multiply(PrimeQ);

int nLen = n.bitLength();

int m=(int)(Math.ceil((double)(nLen)/16.0));

nLen =(nLen-1)/ 16;

String outStr = new String();

outStr = PublicMethod.Encode(inStr,PrimeP,PrimeQ,n,nLen,m,D);

for(i=infileName.length()-1;i>=0;--i)

{

if(infileName.charAt(i)=='.')break;

}

String outfileName = infileName.substring(0,i);

outfileName = outfileName + new String(“.EncodeRsa”)+ infileName.substring(i,infileName.length());

PublicMethod.output(outfileName,outStr);

}

private JTextField P;

private JTextField Q;

private JTextField E;

private JTextField D;

private Frame fr;

int i;

}

class FileDecodeListener implements ActionListener

{

public FileDecodeListener(Frame f,JTextField ap, JTextField aq,JTextField ae,JTextField ad)

{

P = ap;

Q = aq;

E = ae;

D = ad;

fr = f;

}

public void actionPerformed(ActionEvent ee)

{

FileDialog fd = new FileDialog(fr);

fd.setVisible(true);

String infileName =fd.getDirectory()+fd.getFile();

String inStr = new String();

inStr = PublicMethod.input(infileName);

System.out.println(inStr);

BigInteger PrimeP = new BigInteger(P.getText());

BigInteger PrimeQ = new BigInteger(Q.getText());

BigInteger n =PrimeP.multiply(PrimeQ);

int nLen = n.bitLength();

int m=(int)(Math.ceil((double)(nLen)/16.0));

nLen =(nLen-1)/ 16;

String outStr = new String();

outStr = PublicMethod.Decode(inStr,PrimeP,PrimeQ,n,nLen,m,E);

for(i=infileName.length()-1;i>=0;--i)

{

if(infileName.charAt(i)=='.')break;

}

String outfileName = infileName.substring(0,i);

outfileName = outfileName + new String(“.DecodeRsa”)+ infileName.substring(i,infileName.length());

PublicMethod.write(outfileName,outStr);

}

private JTextField P;

private JTextField Q;

private JTextField E;

private JTextField D;

private Frame fr;

int i;

}

class RandListener implements ActionListener

{

public RandListener(JTextField aP, JTextField aQ)

{

P = aP;

Q = aQ;

}

public void actionPerformed(ActionEvent e)

{

PublicMethod.GetPrime(P);

PublicMethod.GetPrime(Q);

}

private JTextField P;

private JTextField Q;

}

class RandDListener implements ActionListener

{

public RandDListener(JTextField aP, JTextField aQ, JTextField ad, JTextField ae)

{

P = aP;

Q = aQ;

d = ad;

e = ae;

}

public void actionPerformed(ActionEvent ee)

{

BigInteger PP = new BigInteger(P.getText());

BigInteger QQ = new BigInteger(Q.getText());

BigInteger temp =(PP.subtract(new BigInteger(“1”))).multiply(QQ.subtract(new BigInteger(“1”)));

BigInteger temp1;

do

{

temp1=new BigInteger(100, new Random()).mod(temp);

}

while(PublicMethod.MillerRobin(temp1)==false);

d.setText(temp1.toString());

e.setText(PublicMethod.invmod(temp1, temp).toString());

}

private JTextField P;

private JTextField Q;

private JTextField d;

private JTextField e;

}

class EncodeListener implements ActionListener

{

public EncodeListener(JTextField aP, JTextField aQ, JTextField ad, JTextField ae,JTextArea in, JTextArea out)

{

P = aP;

Q = aQ;

d = ad;

e = ae;

input = in;

output = out;

}

public void actionPerformed(ActionEvent ee)

{

BigInteger PrimeP = new BigInteger(P.getText());

BigInteger PrimeQ = new BigInteger(Q.getText());

BigInteger n =PrimeP.multiply(PrimeQ);

int nLen = n.bitLength();

int m=(int)(Math.ceil((double)(nLen)/16.0));

nLen =(nLen-1)/ 16;

String inStr = input.getText();

output.setText(PublicMethod.Encode(inStr,PrimeP,PrimeQ,n,nLen,m,e));

}

private JTextField P;

private JTextField Q;

private JTextField d;

private JTextField e;

private JTextArea input;

private JTextArea output;

}

class DecodeListener implements ActionListener

{

public DecodeListener(JTextField aP, JTextField aQ, JTextField ad, JTextField ae,JTextArea out, JTextArea out1)

{

P = aP;

Q = aQ;

d = ad;

e = ae;

output = out;

output1 = out1;

}

public void actionPerformed(ActionEvent ee)

{

BigInteger PrimeP = new BigInteger(P.getText());

BigInteger PrimeQ = new BigInteger(Q.getText());

BigInteger n =PrimeP.multiply(PrimeQ);

int nLen = n.bitLength();

int m=(int)(Math.ceil((double)(nLen)/16.0));

nLen =(nLen-1)/ 16;

String inStr = output.getText();

output1.setText(PublicMethod.Decode(inStr,PrimeP,PrimeQ,n,nLen,m,d));

}

private JTextField P;

private JTextField Q;

private JTextField d;

private JTextField e;

private JTextArea output;

private JTextArea output1;

}

class PublicMethod

{

public static void GetPrime(JTextField prime)

{

BigInteger num = new BigInteger(“0”);

Random rand = new Random();

do

{

int length =(int)(Math.random()*20+100);

System.out.println(length);

num = new BigInteger(length, 5 , rand);

prime.setText(num.toString());

}

while(MillerRobin(num)==false);

}

public static boolean MillerRobin(BigInteger num)

{

int time = 1000;

BigInteger mod = num.mod(new BigInteger(“2”));

if(mod.equals(new BigInteger(“0”)))

{

return false;

}

int s = 0, j=0;

BigInteger t=num.subtract(new BigInteger(“1”));

while(t.mod(new BigInteger(“2”)).equals(“0”))

{

t.divide(new BigInteger(“2”));

++s;

}

for(int i=0;i

{

BigInteger a = new BigInteger(100, new Random()).mod(num.subtract(new BigInteger(“3”))).add(new BigInteger(“2”));

BigInteger y = powmod(a, t, num);

if(y.equals(new BigInteger(“1”))==false

&& y.equals(num.subtract(new BigInteger(“1”)))==false)

{

j=1;

while(j==s&&y.equals(num.subtract(new BigInteger(“1”)))==false)

{

y = y.multiply(y).mod(num);

if(y.equals(new BigInteger(“1”)))

{

return false;

}

++j;

}

if(y.equals(num.subtract(new BigInteger(“1”)))==false)

{

return false;

}

}

}

return true;

}

public static BigInteger powmod(BigInteger a, BigInteger t, BigInteger num)

{

BigInteger A = new BigInteger(“1”);

while(t.equals(new BigInteger(“0”))==false)

{

if(t.mod(new BigInteger(“2”)).equals(new BigInteger(“1”)))

{

A = A.multiply(a).mod(num);

}

a = a.multiply(a).mod(num);

t=t.divide(new BigInteger(“2”));

}

return A;

}

public static BigInteger invmod(BigInteger a, BigInteger b)

{

System.out.println(a+“ ”+b);

BigInteger s0=new BigInteger(“1”), s1=new BigInteger(“0”), s2, q, t, b0=b;

while(b.equals(new BigInteger(“0”))==false)

{

q=a.divide(b);

s2=s0.subtract(q.multiply(s1));

if(s2.compareTo(new BigInteger(“0”))!=-1)

{

s2=s2.mod(b0);

}

else

{

s2=b0.subtract(s2.multiply(new BigInteger(“-1”)).mod(b0));

}

s0=s1;

s1=s2;

t=b;

b=a.mod(b);

a=t;

}

if(a.equals(new BigInteger(“1”)))

{

return s0;

}

else

{

return new BigInteger(“0”);

}

}

public static String Encode(String inStr,BigInteger PrimeP,BigInteger PrimeQ,BigInteger n,int nLen,int m,JTextField d)

{

BigInteger res = new BigInteger(“0”);

StringBuffer outBuf = new StringBuffer();

int i,k,j;

for(i=0;i

{

BigInteger t = new BigInteger(“0”);

for(j=i;j

{

t=t.shiftLeft(16);

long num = inStr.charAt(j);

t=t.add(BigInteger.valueOf(num));

}

res = PublicMethod.powmod(t,new BigInteger(d.getText()),n);

String buf = new String();

for(k=0;k

{

long num =(res.and(BigInteger.valueOf(65535))).longValue();

res = res.shiftRight(16);

buf =(char)(num)+buf;

}

outBuf = outBuf.append(buf);

}

return outBuf.toString();

}

public static String Decode(String inStr,BigInteger PrimeP,BigInteger PrimeQ,BigInteger n,int nLen,int m,JTextField e)

{

StringBuffer outBuf = new StringBuffer();

BigInteger res = new BigInteger(“0”);

int i,j;

for(i=0;i

{

BigInteger t = new BigInteger(“0”);

for(j=0;j

{

t = t.shiftLeft(16);

long num =(long)(inStr.charAt(j+i));

t=t.add(BigInteger.valueOf(num));

}

res = PublicMethod.powmod(t,new BigInteger(e.getText()),n);

String buf = new String();

while(res.compareTo(new BigInteger(“0”))>0)

{

long num =(res.and(BigInteger.valueOf(65535))).longValue();

buf =(char)(num)+ buf;

res = res.shiftRight(16)

;

}

outBuf = outBuf.append(buf);

}

return outBuf.toString();

}

public static String read(String infileName)

{

String ans = new String();

try

{

FileInputStream fis = new FileInputStream(infileName);

InputStreamReader isr = new InputStreamReader(fis);

BufferedReader br = new BufferedReader(isr);

int t;

while(true)

{

t= br.read();

System.out.println(t);

if(t==-1)break;

ans = ans +(char)(t);

}

br.close();

isr.close();

fis.close();

}

catch(FileNotFoundException e)

{

System.out.println(“FileStreamsTest: ”+e);

}

catch(IOException e)

{

System.err.println(“FileStreamsTest: ”+e);

}

System.out.println(“READSTR=”+ans.length());

return ans;

}

public static void write(String outfileName,String outStr)

{

try

{

FileOutputStream fos = new FileOutputStream(outfileName);

OutputStreamWriter osw = new OutputStreamWriter(fos,“UNICODE”);

BufferedWriter out = new BufferedWriter(osw);

int c;

for(int i=0;i

{

c=(int)outStr.charAt(i);

System.out.println(c);

out.write(c);

}

out.close();

osw.close();

fos.close();

}

catch(FileNotFoundException e)

{

System.out.println(“FileStreamsTest: ”+e);

}

catch(IOException e)

{

System.err.println(“FileStreamsTest: ”+e);

}

System.out.println(“WRITE=”+outStr.length());

return;

}

public static String input(String infileName)

{

String ans = new String();

try

{

FileInputStream in = new FileInputStream(infileName);

ObjectInputStream s = new ObjectInputStream(in);

ans =(String)s.readObject();

s.close();

in.close();

}

catch(FileNotFoundException e)

{

System.out.println(“FileStreamsTest: ”+e);

}

catch(IOException e)

{

System.err.println(“FileStreamsTest: ”+e);

}

catch(ClassNotFoundException e)

{

System.out.println(“FileStreamsTest: ”+e);

}

return ans;

}

public static void output(String outfileName,String outStr)

{

try

{

FileOutputStream f = new FileOutputStream(outfileName);

ObjectOutputStream s = new ObjectOutputStream(f);

s.writeObject(outStr);

s.close();

f.close();

}

catch(FileNotFoundException e)

{

System.out.println(“FileStreamsTest: ”+e);

}

catch(IOException e)

{

System.err.println(“FileStreamsTest: ”+e);

}

} }

六 实验结果及分析

实验结果如图6-1所示

图6-1 运行结果界面

运行程序,弹出的对话框如上图所示。

点击按钮“生成质数P和Q”,自动生成质数P和质数Q; 然后点击按钮“生成公钥和私钥”,就自动生成公钥和私钥; 输入明文:密码学有点意思

点击“加密”按钮,生成的密文如上图所示。点击“解密”按钮,即可解密密文。如图。

图6-2 Java运行界面

七 实验小结

本次实验对输入的任意一段明文字母,实现了输出对应密钥的密文字母。亲手实际编写RSA密码算法代码,更好的了解和掌握了RSA的相关内容。通过用Java对RSA密码体制进行编程,对RSA密码体制的加解密过程有了更深入的理解。通过这个实验更是让我获得了很多实际工作中所要具备的能力。

第二篇:RSA算法实验报告

信息安全实验报告

题 目 RSA算法 姓 名 学 号

专业年级 计算机科学与技术2014级(1)班 指导教师

2016年 12 月 10日

一、实验目的

了解非对称加密机制 理解RSA算法的加解密原理

熟悉Java的学习以及运用Java实现RSA算法的加解密过程

二、实验背景

钥密码体制中,加密密钥(即公开密钥)PK是公开信息,而解密密钥(即秘密密钥)SK是需要保密的。加密算法E和解密算法D也都是公开的。虽然秘密密钥SK是由公开密钥PK决定的,但却不能根据PK计算出SK。正是基于这种理论,1978年出现了著名的RSA算法,它通常是先生成一对RSA 密钥,其中之一是保密密钥,由用户保存;另一个为公开密钥,可对外公开,甚至可在网络服务器中注册。为提高保密强度,RSA密钥至少为500位长,一般推荐使用1024位。这就使加密的计算量很大。为减少计算量,在传送信息时,常采用传统加密方法与公开密钥加密方法相结合的方式,即信息采用改进的DES或IDEA对话密钥加密,然后使用RSA密钥加密对话密钥和信息摘要。对方收到信息后,用不同的密钥解密并可核对信息摘要。RSA算法是第一个能同时用于加密和数字签名的算法,也易于理解和操作。RSA是被研究得最广泛的公钥算法,从提出到现在的这么多年里,经历了各种攻击的考验,逐渐为人们接受,普遍认为是目前最优秀的公钥方案之一。

三、实验原理

1.非对称密钥加解密概述

使用对称密钥加密体制进行保密通信时,任意不同的两个用户之间都应该使用互不相同的密钥。这样,如果一个网络中有n个用户,他们之间彼此都可能进行秘密通信,这时网络中将需要n(n-1)/2个密钥(其中,每个用户都需要保存n-1个密钥),这样巨大的密钥量给密钥分配和管理带来了极大的困难。另外,随着计算机网络,特别是因特网的发展,网络上互不相识的用户可能需要进行保密的会话(例如,如果用户在进行电子商务活动时,需要保密的连接,这时的客户对象可能根本不是固定的对象)。最后,对称密钥加密机制难以解决签名验证问题。

非对称密钥加密也称为公开密钥加密,或者叫做公钥加密算法。使用公开密钥密码的每一个用户都分别拥有两个密钥:加密密钥和解密密钥,它们两者并不相同,并且由加密密钥得到解密密钥在计算机上是不可行的。每一个用户的加密密钥都是公开的。因此,加密密钥也称为公开密钥。所有用户的公开密钥都将记录在作用类似于电话号码薄的密钥本上,而它可以被所有用户访问,这样每一个用户都可以得到其他所有用户的公开密钥。同时,每一个用户的解密密钥将由用户保存并严格保密。因此,解密密钥也称为私有密钥。

非对称密码算法解决了对称密码体制中密钥管理的难题,并提供了对信息发送人的身份进行验证的手段,是现代密码学最重要的发明。公钥加密算法一般是将对密钥的求解转化为对数学上的困难问题的求解,例如RSA算法的安全性是建立在“大数分解和素性检测”这个数论难题的基础上,已知两个大素数a和b,求出a*b是容易计算的,而已知a*b,想知道其是哪两个大素数的乘积目前还没有好的计算方法,另外也有一些非对称加密算法(如ELGamal算法)的安全性是基于求“离散对数”这个数学难题上的。

在公钥密码系统中每个实体都有自己的公钥和相应的私钥。公钥密码系统的加密变换和解密变换分别用E和D表示。任何实体B要向实体A发送信息m的步骤如下:实体B首先获得实体A的真实公钥的拷贝(eA),实体B使用eA计算密文c=E(m)并发送给实体A,实体A使用自己的私钥dA,计算m=D(c)解密密文,恢复出明文m。这里公钥不需要保密,但要保证它的真实性,即eA确实是实体A掌握的私钥dA所对应的公钥。提供真实的公钥比安全地分配密钥实现起来要容易得多。这也是公钥密码系统的主要优点之一。

公钥密码系统的主要目的是提供保密性,它不能提供数据源认证(data origin authentication)和数据完整性(data integrity)。数据源认证是指:指定的数据是在以前的某个时间确实是由真正的源创建的。数据完整性是指:真正的源创建该数据后经过传输后存储没有发生改变。数据源认证和数据完整性要由其他技术来提供(如消息认证码技术、数字签名技术等)。

从本质上来看,公钥密码比对称密钥密码加密的速度要慢,粗略的说,公钥加密算法RSA硬件实现比分组加密算法DES硬件实现的速度慢1500倍,而软件实现的速度要慢100倍。

公钥解密也可以提供认证保证(如:在实体认证协议、带认证的密钥建立协议等)。公钥加密中必须有颁发让发送消息的人得到想要发送到的那个人的公钥的真实拷贝,否则就会受到伪装攻击。在实践中有很多方法分发真实的公钥,如:使用可信的公共文件,使用在线可信服务器,使用离线服务器和认证。

2.公钥加解密的优缺点:

1)大型网络中的每个用户需要的密钥数量少。

2)对管理公钥的可信第三方的信任程度要求不高而且是离线的。3)只有私钥是保密的,而公钥只要保证它的真实性。4)多数公钥加密比对称密钥加密的速度要慢几个数量级。5)公钥加密方案的密钥长度比对称加密的密钥要长。6)公钥加密方案没有被证明是安全的。

公钥密码的概念本身就被公认为是密码学上的一块里程碑。三十多年来的研究表明,公钥密码成功地解决了计算机网络安全中的密钥管理,身份认证和数字签名等问题,已经成为信息安全技术中的重大核心技术。

四、RSA算法 1.概述

RSA加密算法于1977年由美国麻省理工学院的Ronal Rivest,Adi Shamir和Len Adleman三位年轻教授提出,并以三人的姓氏Rivest,Shamir和Adleman命名为RSA算法。这三位科学家荣获2002图灵奖,以表彰他们在算法方面的突出贡献。该算法利用了数论领域的一个事实,那就是虽然把两个大质数相乘生成一个合数是件十分容易的事情,但要把一个合数分解为两个质数的乘积却十分困难。合数分解问题目前仍然是数学领域尚未解决的一大难题,至今没有任何高效的分解方法。它无须收发双方同时参与加密过程,既可以用于保密也可以用于签名,因而非常适合于电子邮件系统的加密,互连网和信用卡安全系统。

算法概述:找两素数p和q,取n=p*q,取t=(p-1)*(q-1),取任何一个数e,要求满足e

2.算法设计

1)publicstaticvoid GetPrime()说明:利用Java语言的中的java.math.BigInteger类的方法中随机产生大数。

2)public static boolean MillerRobin(BigInteger num)参数说明:num是由GetPrime方法产生的大数。

说明:这个方法判断GetPrime方法传过来的是否是一个素数,是就返回true,否就返回false。

3)public static BigInteger powmod(BigIntegera,BigIntegert,BigInteger num)说明:这个方法对传入的大数进行幂运算。

4)public static BigInteger invmod(BigInteger a,BigInteger b)说明:这个方法对大数进行取模运算。

5)public static String Encode(String inStr,BigInteger PrimeP,BigInteger PrimeQ,BigInteger n,int nLen,int m,JTextFieldd)方法名称:加密算法。参数说明:

inStr是从界面输入的明文。

PrimeP和PrimeQ是由GetPrime方法产生的两个大素数。n是由PrimeP和PrimeQ得到的值。nLen为n的长度。d为公钥。

6)publicstatic String Decode(String inStr,BigInteger PrimeP,BigInteger PrimeQ,BigInteger n,int nLen,int m,JTextField e)方法名称:解密算法。参数说明:

inStr是从界面输入的明文。

PrimeP和PrimeQ是由GetPrime方法产生的两个大素数。n是由PrimeP和PrimeQ得到的值。nLen为n的长度。e为私钥。

在对称加密中:n,d两个数构成公钥,可以告诉别人;n,e两个数构成私钥,e自己保留,不让任何人知道。给别人发送的信息使用e加密,只要别人能用d解开就证明信息是由你发送的,构成了签名机制。别人给你发送信息时使用d加密,这样只有拥有e的你能够对其解密。

RSA的安全性在于对于一个大数n,没有有效的方法能够将其分解从而在已知n,d的情况下无法获得e;同样在已知n,e的情况下无法求得d。

五、实验结果

实验结果如下图所示:

六、实验总结

本次实验对输入的任意一段明文字母,实现了输出对应密钥的密文字母。亲手实际编写RSA密码算法代码,更好的了解和掌握了RSA的相关内容。通过用Java对RSA密码体制进行编程,对RSA密码体制的加解密过程有了更深入的理解。通过这个实验更是让我获得了很多实际工作中所要具备的能力。

七、代码附录

第三篇:RSA加密解密算法C语言代码

#include #include #include

#include

#include #include #define MAX 100 #define LEN sizeof(struct slink)

void sub(int a[MAX],int b[MAX] ,int c[MAX]);

struct slink {

int bignum[MAX];/*bignum[98]用来标记正负号,1正,0负bignum[99]来标记实际长度*/

struct slink *next;};

/*/-------自己建立的大数运算库------*/

void print(int a[MAX])

{

int i;

for(i=0;i

printf(“%d”,a[a[99]-i-1]);

printf(“nn”);

return;

}

int cmp(int a1[MAX],int a2[MAX]){

int l1, l2;int i;l1=a1[99];l2=a2[99];if(l1>l2)

return 1;

if(l1

return-1;

for(i=(l1-1);i>=0;i--)

{

if(a1[i]>a2[i])

return 1;

if(a1[i]

return-1;

}

return 0;}

void mov(int a[MAX],int *b){ int j;

for(j=0;j

b[j]=a[j];

return;}

void mul(int a1[MAX],int a2[MAX],int *c){ int i,j;int y;int x;int z;int w;int l1, l2;l1=a1[MAX-1];l2=a2[MAX-1];if(a1[MAX-2]=='-'&& a2[MAX-2]=='-')

c[MAX-2]=0;else if(a1[MAX-2]=='-')

c[MAX-2]='-';else if(a2[MAX-2]=='-')

c[MAX-2]='-';for(i=0;i

for(j=0;j

{

x=a1[i]*a2[j];

y=x/10;

z=x%10;

w=i+j;

c[w]=c[w]+z;

c[w+1]=c[w+1]+y+c[w]/10;

c[w]=c[w]%10;

} } w=l1+l2;if(c[w-1]==0)w=w-1;c[MAX-1]=w;return;}

void add(int a1[MAX],int a2[MAX],int *c){

int i,l1,l2;int len,temp[MAX];int k=0;l1=a1[MAX-1];l2=a2[MAX-1];if((a1[MAX-2]=='-')&&(a2[MAX-2]=='-')){ c[MAX-2]='-';} else if(a1[MAX-2]=='-'){ mov(a1,temp);temp[MAX-2]=0;sub(a2,temp,c);return;} else if(a2[MAX-2]=='-'){ mov(a2,temp);temp[98]=0;sub(a1,temp,c);return;}

if(l1

c[i]=(a1[i]+a2[i]+k)%10;

k=(a1[i]+a2[i]+k)/10;} if(l1>len){

for(i=len;i

{

c[i]=(a1[i]+k)%10;

k=(a1[i]+k)/10;

}

if(k!=0)

{

c[l1]=k;

len=l1+1;

}

else len=l1;} else {

for(i=len;i

{

c[i]=(a2[i]+k)%10;

k=(a2[i]+k)/10;

}

if(k!=0)

{

c[l2]=k;

len=l2+1;

}

else len=l2;}

c[99]=len;

return;}

void sub(int a1[MAX],int a2[MAX],int *c){ int i,l1,l2;int len,t1[MAX],t2[MAX];int k=0;l1=a1[MAX-1];l2=a2[MAX-1];if((a1[MAX-2]=='-')&&(a2[MAX-2]=='-')){ mov(a1,t1);

mov(a2,t2);t1[MAX-2]=0;

t2[MAX-2]=0;sub(t2,t1,c);return;} else if(a2[MAX-2]=='-'){ mov(a2,t2);t2[MAX-2]=0;add(a1,t2,c);return;} else if(a1[MAX-2]=='-'){ mov(a2,t2);t2[MAX-2]='-';add(a1,t2,c);return;}

if(cmp(a1,a2)==1){

len=l2;for(i=0;i

if((a1[i]-k-a2[i])<0){

c[i]=(a1[i]-a2[i]-k+10)%10;

k=1;}

else

{

c[i]=(a1[i]-a2[i]-k)%10;

k=0;

} }

for(i=len;i

{

if((a1[i]-k)<0){

c[i]=(a1[i]-k+10)%10;

k=1;}

else

{

c[i]=(a1[i]-k)%10;

k=0;

}

}

if(c[l1-1]==0)/*使得数组C中的前面所以0字符不显示了,如1000-20=0980--->显示为980了*/

{

len=l1-1;

i=2;

while(c[l1-i]==0)/*111456-111450=00006,消除0后变成了6;*/

{

len=l1-i;

i++;

}

}

else

{

len=l1;

} } else if(cmp(a1,a2)==(-1)){

c[MAX-2]='-';

len=l1;

for(i=0;i

if((a2[i]-k-a1[i])<0){

c[i]=(a2[i]-a1[i]-k+10)%10;

k=1;}

else

{

c[i]=(a2[i]-a1[i]-k)%10;

k=0;

} }

for(i=len;i

{

if((a2[i]-k)<0){

c[i]=(a2[i]-k+10)%10;

k=1;}

else

{

c[i]=(a2[i]-k)%10;

k=0;

}

}

if(c[l2-1]==0)

{

len=l2-1;

i=2;

while(c[l1-i]==0)

{

len=l1-i;

i++;

}

}

else len=l2;

}

else if(cmp(a1,a2)==0)

{

len=1;

c[len-1]=0;

} c[MAX-1]=len;return;}

void mod(int a[MAX],int b[MAX],int *c)/*/c=a mod b//注意:经检验知道此处A和C的数组都改变了。*/ { int d[MAX];mov(a,d);while(cmp(d,b)!=(-1))/*/c=a-b-b-b-b-b.......until(c

sub(d,b,c);

mov(c,d);/*/c复制给a*/ }

return;}

void divt(int t[MAX],int b[MAX],int *c ,int *w)/*//试商法//调用以后w为a mod b, C为a div b;*/ {

int a1,b1,i,j,m;/*w用于暂时保存数据*/ int d[MAX],e[MAX],f[MAX],g[MAX],a[MAX];

mov(t,a);

for(i=0;i

e[i]=0;for(i=0;i

d[i]=0;for(i=0;i

b1=b[MAX-1];if(cmp(a,b)==(-1)){

c[0]=0;

c[MAX-1]=1;

mov(t,w);

return;} else if(cmp(a,b)==0){

c[0]=1;

c[MAX-1]=1;

w[0]=0;

w[MAX-1]=1;

return;}

m=(a1-b1);

for(i=m;i>=0;i--)/*341245/3=341245-300000*1--->41245-30000*1--->11245-3000*3--->2245-300*7--->145-30*4=25--->25-3*8=1*/ {

for(j=0;j

d[j]=0;

d[i]=1;

d[MAX-1]=i+1;

mov(b,g);

mul(g,d,e);

while(cmp(a,e)!=(-1))

{

c[i]++;

sub(a,e,f);

mov(f,a);/*f复制给g*/

}

for(j=i;j

e[j]=0;

} mov(a,w);if(c[m]==0)c[MAX-1]=m;else c[MAX-1]=m+1;

return;}

void mulmod(int a[MAX] ,int b[MAX] ,int n[MAX],int *m)/*解决 了 m=a*b mod n;*/ { int c[MAX],d[MAX];int i;for(i=0;i

d[i]=c[i]=0;mul(a,b,c);

divt(c,n, d,m);

for(i=0;i

printf(“%d”,m[m[MAX-1]-i-1]);

printf(“nm length is : %d n”,m[MAX-1]);}

/*接下来的重点任务是要着手解决 m=a^p mod n的函数问题。*/

void expmod(int a[MAX] ,int p[MAX] ,int n[MAX],int *m){ int t[MAX],l[MAX],temp[MAX];/*/t放入2,l放入1;*/ int w[MAX],s[MAX],c[MAX],b[MAX],i;for(i=0;i

b[i]=l[i]=t[i]=w[i]=0;t[0]=2;t[MAX-1]=1;l[0]=1;l[MAX-1]=1;

mov(l,temp);mov(a,m);

mov(p,b);

while(cmp(b,l)!=0){

for(i=0;i

divt(b,t,w,c);/*// c=p mod 2 w= p /2*/

mov(w,b);/*//p=p/2*/

if(cmp(c,l)==0)/*/余数c==1*/ { for(i=0;i

mul(temp,m,w);

mov(w,temp);

for(i=0;i

divt(temp,n,w,c);/* /c为余c=temp % n,w为商w=temp/n */

mov(c,temp);}

for(i=0;i

mul(m,m,s);//s=a*a

for(i=0;i

divt(s,n,w,c);/*/w=s/n;c=s mod n*/

mov(c,m);}

for(i=0;i

mul(m,temp,s);

for(i=0;i

divt(s,n,w,c);

mov(c,m);/*余数s给m*/

m[MAX-2]=a[MAX-2];/*为后面的汉字显示需要,用第99位做为标记*/

return;/*/k=temp*k%n;*/ }

int

is_prime_san(int p[MAX]){

int i,a[MAX],t[MAX],s[MAX],o[MAX];

for(i=0;i

s[i]=o[i]=a[i]=t[i]=0;

t[0]=1;

t[MAX-1]=1;

a[0]=2;// { 2,3,5,7 }

a[MAX-1]=1;

sub(p,t,s);

expmod(a, s, p ,o);

if(cmp(o,t)!= 0)

{

return 0;

}

a[0]=3;

for(i=0;i

expmod(a, s, p ,o);

if(cmp(o,t)!= 0)

{

return 0;

}

a[0]=5;

for(i=0;i

expmod(a, s, p ,o);

if(cmp(o,t)!= 0)

{

return 0;

}

a[0]=7;

for(i=0;i

expmod(a, s, p ,o);

if(cmp(o,t)!= 0)

{

return 0;

}

return 1;}

int coprime(int e[MAX],int s[MAX])/*//// 求两个大数之间是否互质////*/ {

int a[MAX],b[MAX],c[MAX],d[MAX],o[MAX],l[MAX];

int i;for(i=0;i

l[i]=o[i]=c[i]=d[i]=0;o[0]=0;o[MAX-1]=1;l[0]=1;l[MAX-1]=1;mov(e,b);mov(s,a);do { if(cmp(b,l)==0){

return 1;} for(i=0;ia*/ mov(c,b);/*c--->b*/

}while(cmp(c,o)!=0);/* printf(“Ihey are not coprime!n”);*/ return 0;}

void prime_random(int *p,int *q){ int i,k;time_t t;

p[0]=1;

q[0]=3;

// p[19]=1;// q[18]=2;

p[MAX-1]=10;

q[MAX-1]=11;

do {

t=time(NULL);

srand((unsigned long)t);for(i=1;i

k=rand()%10;} p[p[MAX-1]-1]=k;

}while((is_prime_san(p))!=1);

printf(“素数 p 为

: ”);

for(i=0;i

printf(“nn”);

do {

t=time(NULL);

srand((unsigned long)t);for(i=1;i

}while((is_prime_san(q))!=1);

printf(“素数 q 为 : ”);

for(i=0;i

printf(“nn”);return;}

void erand(int e[MAX],int m[MAX]){ int i,k;time_t t;e[MAX-1]=5;printf(“随机产生一个与(p-1)*(q-1)互素的 e :”);

do {

t=time(NULL);

srand((unsigned long)t);for(i=0;i

k=rand()%10;e[e[MAX-1]-1]=k;}while(coprime(e, m)!=1);

for(i=0;i

printf(“nn”);return;}

void rsad(int e[MAX],int g[MAX],int *d){ int

r[MAX],n1[MAX],n2[MAX],k[MAX],w[MAX];int

i,t[MAX],b1[MAX],b2[MAX],temp[MAX];mov(g,n1);mov(e,n2);for(i=0;i

k[i]=w[i]=r[i]=temp[i]=b1[i]=b2[i]=t[i]=0;b1[MAX-1]=0;b1[0]=0;/*/b1=0;*/ b2[MAX-1]=1;b2[0]=1;/*/b2=1;*/ while(1){

for(i=0;i

k[i]=w[i]=0;

divt(n1,n2,k,w);/*/k=n1/n2;*/

for(i=0;i

temp[i]=0;

mul(k,n2,temp);/*/temp=k*n2;*/

for(i=0;i

r[i]=0;

sub(n1,temp,r);

if((r[MAX-1]==1)&&(r[0]==0))/*/r=0*/

{

break;

}

else

{

mov(n2,n1);/*/n1=n2;*/

mov(r,n2);/*/n2=r;*/

mov(b2, t);/*/t=b2;*/

for(i=0;i

temp[i]=0;

mul(k,b2,temp);/*/b2=b1-k*b2;*/

for(i=0;i

b2[i]=0;

sub(b1,temp,b2);

mov(t,b1);

} }

for(i=0;i

t[i]=0;

add(b2,g,t);

for(i=0;i

temp[i]=d[i]=0;

divt(t,g,temp,d);

printf(“由以上的(p-1)*(q-1)和 e 计算得出的 d : ”);

for(i=0;i

printf(“nn”);}

/*/求解密密钥d的函数(根据Euclid算法)***68000*/ unsigned long rsa(unsigned long p,unsigned long q,unsigned long e)/*/求解密密钥d的函数(根据Euclid算法)*/ { unsigned long g,k,r,n1,n2,t;unsigned long b1=0,b2=1;

g=(p-1)*(q-1);n1=g;n2=e;

while(1){

k=n1/n2;

r=n1-k*n2;

if(r!=0)

{

n1=n2;

n2=r;

t=b2;

b2=b1-k*b2;

b1=t;

}

else

{

break;

}

}

return(g+b2)%g;} /*/-----------导入导出公钥和私钥-----/*/ void loadpkey(int e[MAX],int n[MAX])//导入公钥 { FILE *fp;char filename[25],str[MAX],ch;int i,k;for(i=0;i

e[i]=n[i]=0;while(1){

printf(“n”);printf(“为导入(e,n),请输入加密密钥对文件路径: n”);

scanf(“%s”,filename);

if((fp=fopen(filename,“r”))==NULL)

printf(“输入的文件不存在,请重新输入!n”);

else break;}

k=0;

while((ch=fgetc(fp))!=EOF)

{

if(ch!=' ')

{

str[k]=ch;

k++;

}

else

{

for(i=0;i

{

e[i]=str[k-i-1]-48;

}

e[MAX-1]=k;

k=0;

} }

for(i=0;i

n[i]=str[k-i-1]-48;

n[MAX-1]=k;

printf(“n加密密钥 e : ”);

for(i=0;i

printf(“%d”,e[e[MAX-1]-i-1]);

printf(“n”);

printf(“n

公钥 n : ”);

for(i=0;i

printf(“%d”,n[n[MAX-1]-i-1]);

printf(“n”);

fclose(fp);

printf(“n导入(e,n)成功!n”);

getchar();}

void loadskey(int d[MAX],int n[MAX])//导入私钥 { { FILE *fp;char filename[25],str[MAX],ch;int i,k;for(i=0;i

d[i]=n[i]=0;while(1){ printf(“为导入(d,n),请输入解密密钥对文件的路径: n”);

scanf(“%s”,filename);

if((fp=fopen(filename,“r”))==NULL)

{

printf(“输入的文件不存在,请重新输入!n”);

}

else break;}

k=0;

while((ch=fgetc(fp))!=EOF)

{

if(ch!=' ')

{

str[k]=ch;

k++;

}

else

{

for(i=0;i

{

d[i]=str[k-i-1]-48;

}

d[MAX-1]=k;

k=0;

} }

for(i=0;i

n[i]=str[k-i-1]-48;

n[MAX-1]=k;

printf(“n解密密钥 d : ”);

for(i=0;i

printf(“%d”,d[d[MAX-1]-i-1]);

printf(“n”);

printf(“n

公钥 n : ”);

for(i=0;i

printf(“%d”,n[n[MAX-1]-i-1]);

printf(“n”);

fclose(fp);

printf(“n导入(d,n)成功!n”);

getchar();} }

void savepkey(int e[MAX],int n[MAX])//导出公钥 {

FILE *fp;

int i;

char savefile[25],ch;printf(“导出加密密钥(e,n),存放的文件路径为: ”);

scanf(“%s”,savefile);printf(“n”);

fp=fopen(savefile,“w”);for(i=0;i

ch=e[e[MAX-1]-i-1]+48;

fputc(ch,fp);} ch=' ';fputc(ch,fp);for(i=0;i

ch=n[n[MAX-1]-i-1]+48;

fputc(ch,fp);} fclose(fp);printf(“n保存(e,n)操作完成!n”);}

void saveskey(int d[MAX],int n[MAX])//导出私钥 {

FILE *fp;

int i;

char savefile[25],ch;printf(“导出解密密钥(d,n),存放的文件路径为: ”);

scanf(“%s”,savefile);printf(“n”);

fp=fopen(savefile,“w”);for(i=0;i

ch=d[d[MAX-1]-i-1]+48;

fputc(ch,fp);} ch=' ';fputc(ch,fp);for(i=0;i

ch=n[n[MAX-1]-i-1]+48;

fputc(ch,fp);} fclose(fp);printf(“n保存(d,n)操作完成!n”);

}

/*/-----------加密和解密的块-----/*/

void printbig(struct slink *h){

struct slink *p;

int i;

p=(struct slink *)malloc(LEN);

p=h;

if(h!=NULL)do

{

for(i=0;i

bignum[MAX-1];i++)

printf(“%d”,p->bignum[p->bignum[MAX-1]-i-1]);

p=p->next;}

while(p!=NULL);

printf(“nn”);

}

void tencrypto(int e[MAX], int n[MAX])/*//对有需要的文件进行加密*/ {

FILE *fp;

int i,k,count,temp,c;

char filename[25],ch,encryfile[25];

struct slink *p,*p1,*p2;

struct slink *h;

h=p=p1=p2=(struct slink *)malloc(LEN);

h=NULL;

printf(“n输入需要加密的文件路径 : ”);

scanf(“%s”,filename);

if((fp=fopen(filename,“r”))==NULL)

{

printf(“Cannot open file!n”);

exit(0);

} printf(“n文件的原文内容:nn”);

count=0;

while((ch=fgetc(fp))!=EOF)

{

putchar(ch);

c=ch;

k=0;if(c<0){

c=abs(c);/*/把负数取正并且做一个标记*/

p1->bignum[MAX-2]='0';} else {

p1->bignum[MAX-2]='1';}

while(c/10!=0){

temp=c%10;

c=c/10;

p1->bignum[k]=temp;

k++;} p1->bignum[k]=c;

p1->bignum[MAX-1]=k+1;count=count+1;if(count==1)

h=p1;else p2->next=p1;p2=p1;

p1=(struct slink *)malloc(LEN);}

p2->next=NULL;

printf(“n”);

fclose(fp);

//

printf(“加密后文件的保存路径 : n”);//

scanf(“%s”,encryfile);//

fp=fopen(encryfile,“w”);

fp=fopen(filename,“w”);

p=p1=(struct slink *)malloc(LEN);

p=h;

printf(“n加密后文件中所形成密文:nn”);

if(h!=NULL)do

{

expmod(p->bignum , e ,n ,p1->bignum);

ch=p1->bignum[MAX-2];

printf(“%c”,ch);

fputc(ch,fp);

if((p1->bignum[MAX-1]/10)==0)/*/判断p1->bignum[99]的是否大于十;*/

{

ch=0+48;

printf(“%c”,ch);

fputc(ch,fp);

ch=p1->bignum[MAX-1]+48;

printf(“%c”,ch);

fputc(ch,fp);

}

else

{

ch=p1->bignum[MAX-1]/10+48;

printf(“%c”,ch);

fputc(ch,fp);

ch=p1->bignum[MAX-1]%10+48;

printf(“%c”,ch);

fputc(ch,fp);

}

for(i=0;i

bignum[MAX-1];i++)

{

printf(“%d”,p1->bignum[i]);

ch=p1->bignum[i]+48;

fputc(ch,fp);

}

p=p->next;

p1=(struct slink *)malloc(LEN);}while(p!=NULL);printf(“nn”);

fclose(fp);return;}

void tdecrypto(int d[MAX], int n[MAX]){

FILE *fp;

struct slink *h,*p1,*p2;

char ch,encryfile[25],decryfile[25];

int i,j,k,c,count,temp;

printf(“n输入加密过的文件路径 : ”);

scanf(“%s”,encryfile);

if((fp=fopen(encryfile,“r”))==NULL)

{

printf(“此文件不存在!n”);

exit(0);

}

printf(“n文件中密文内容:nn”);

i=0;

j=3;

count=0;

h=p1=p2=(struct slink *)malloc(LEN);

while((ch=fgetc(fp))!=EOF)

{

putchar(ch);

c=ch;

if(j==3)

{

p1->bignum[MAX-2]=c;

j--;

}

else if(j==2)

{

temp=c-48;

j--;

}

else if(j==1)

{

p1->bignum[MAX-1]=temp*10+c-48;

j--;

}

else if(j==0)

{

p1->bignum[i]=c-48;

i++;

if(i==p1->bignum[MAX-1])

{

i=0;

j=3;

count++;

if(count==1)

h=p1;

else p2->next=p1;

p2=p1;

p1=(struct slink *)malloc(LEN);

}

}

}

p2->next=NULL;

printf(“n”);

fclose(fp);

// printf(“解密后的明文文件保存路径 : n”);//

scanf(“%s”,decryfile);//

fp=fopen(decryfile,“w”);

fp=fopen(encryfile,“w”);printf(“n解密密文后文件中的明文:nn”);p2=(struct slink *)malloc(LEN);

p1=h;k=0;if(h!=NULL)/*/temp为暂存ASIIC码的int值*/

do

{

for(i=0;i

p2->bignum[i]=0;

expmod(p1->bignum , d ,n ,p2->bignum);

temp=p2->bignum[0]+p2->bignum[1]*10+p2->bignum[2]*100;

if((p2->bignum[MAX-2])=='0')

{

temp=0-temp;

}/*/转化为正确的ASIIC码,如-78-96形成汉字 */

ch=temp;/* str[k]--->ch */

printf(“%c”,ch);/* str[k]--->ch */

fputc(ch,fp);/*/写入文件str[k]--->ch*/

k++;

p1=p1->next;

p2=(struct slink *)malloc(LEN);

}while(p1!=NULL);

printf(“nn”);

fclose(fp);return;}

struct slink *input(void)/*/输入明文并且返回头指针,没有加密时候转化的数字*/ {

struct slink *head;

struct slink *p1,*p2;

int i,n,c,temp;

char ch;

n=0;p1=p2=(struct slink *)malloc(LEN);head=NULL;printf(“n请输入你所要加密的内容 : n”);while((ch=getchar())!='n')

{ i=0;c=ch;if(c<0){

c=abs(c);/*/把负数取正并且做一个标记*/

p1->bignum[MAX-2]='0';}

else {

p1->bignum[MAX-2]='1';} while(c/10!=0){

temp=c%10;

c=c/10;

p1->bignum[i]=temp;

i++;} p1->bignum[i]=c;

p1->bignum[MAX-1]=i+1;n=n+1;if(n==1)

head=p1;else p2->next=p1;p2=p1;

p1=(struct slink *)malloc(LEN);}

p2->next=NULL;

return(head);}

struct slink *jiami(int e[MAX],int n[MAX],struct {

struct slink *p;

struct slink *h;

struct slink *p1,*p2;

int m=0,i;printf(“n”);

printf(“加密后形成的密文内容:n”);p1=p2=(struct slink*)malloc(LEN);h=NULL;

p=head;

if(head!=NULL)do

slink *head){

expmod(p->bignum , e ,n ,p1->bignum);

for(i=0;i

bignum[MAX-1];i++){

printf(“%d”,p1->bignum[p1->bignum[MAX-1]-1-i]);}

m=m+1;if(m==1)

h=p1;else p2->next=p1;p2=p1;

p1=(struct slink *)malloc(LEN);

p=p->next;} while(p!=NULL);p2->next=NULL;

p=h;

printf(“n”);

return(h);

}

void jiemi(int d[MAX],int n[MAX],struct slink *h){

int

i,j,temp;

struct slink *p,*p1;

char ch[65535];

p1=(struct slink*)malloc(LEN);

p=h;

j=0;

if(h!=NULL)

do

{

for(i=0;i

p1->bignum[i]=0;

expmod(p->bignum , d ,n ,p1->bignum);

temp=p1->bignum[0]+p1->bignum[1]*10+p1->bignum[2]*100;

if((p1->bignum[MAX-2])=='0')

{

temp=0-temp;

}

ch[j]=temp;

j++;

p=p->next;}while(p!=NULL);printf(“n”);printf(“解密密文后所生成的明文:n”);for(i=0;i

printf(“%c”,ch[i]);printf(“n”);return;

}

void menu(){

printf(“nnn”);printf(“nnn”);printf(“

R--------产生密钥对

nnn”);

printf(“

S--------保存密钥对

nnn”);printf(“

L--------载入密钥对

nnn”);printf(“

E--------对文件加密

nnn”);printf(“

D--------对文件解密

nnn”);printf(“

T--------简单测试

nnn”);printf(“

Q--------退出

nnn”);printf(“请选择一种操作:”);}

/*/------------------主MAIN函数----/*/ void main(){

int i;

char c;

int p[MAX],q[MAX],n[MAX],d[MAX],e[MAX],m[MAX],p1[MAX],q1[MAX];struct slink *head,*h1,*h2;

for(i=0;i

m[i]=p[i]=q[i]=n[i]=d[i]=e[i]=0;/*/简单初始化一下*/

while(1)

{

menu();

c=getchar();

getchar();//接受回车符

if((c=='r')||(c=='R'))//操作r产生密钥对

{

for(i=0;i

m[i]=p[i]=q[i]=n[i]=d[i]=e[i]=0;

printf(“nnnnnnnnn”);

printf(“nn随机密钥对产生如下:nn”);

prime_random(p,q);/*/随机产生两个大素数*/

mul(p,q,n);

printf(“由 p、q 得出 n :”);

print(n);

mov(p,p1);

p1[0]--;

mov(q,q1);

q1[0]--;

/*/q-1;*/

mul(p1,q1,m);//m=(p-1)*(q-1)

erand(e,m);

rsad(e,m,d);

printf(“密钥对产生完成,现在可以直接进行加解密文件!n”);

printf(“n按任意键回主菜单…………”);

getchar();}

else if((c=='l')||(c=='L'))

{

printf(“nn选择导入密钥类型:加密密钥(P)还是解密密钥(S)?”);

c=getchar();

getchar();

if((c=='p')||(c=='P'))

loadpkey(e,n);

else if((c=='s')||(c=='S'))

loadskey(d,n);

printf(“n按任意键回主菜单…………”);

getchar();

}

else if((c=='e')||(c=='E'))

{

tencrypto(e, n);

printf(“n加密文件操作完成!n”);

printf(“n按任意键回主菜单…………”);

getchar();

getchar();

}

else if((c=='d')||(c=='D'))

{

tdecrypto(d, n);

printf(“n解密文件操作完成!n”);

printf(“n按任意键回主菜单…………”);

getchar();

getchar();

}

else if((c=='s')||(c=='S'))

{

savepkey(e,n);

printf(“n”);

saveskey(d,n);

printf(“n按任意键回主菜单…………”);

getchar();

getchar();

}

else if((c=='T')||(c=='t'))

{

head=input();

h1=jiami(e, n, head);

jiemi(d, n, h1);

printf(“nRSA测试工作完成!n”);

printf(“n按任意键回主菜单…………”);

getchar();

}

else if((c=='Q')||(c=='q'))

break;

}

}

第四篇:RSA数字签名在电子商务中的应用

RSA数字签名算法探析

摘 要

随着电子商务飞速发展、普及和应用,安全问题已经成为电子商务发展的瓶颈。本文从电子商务交易过程对电子商务安全性的需求出发,介绍了数字签名的原理,着重介绍了RSA加密算法的工作原理及其在电子商务中的应用。

关 键 词

RSA;加密算法;电子商务

Abstract Along with the electronic commerce rapid development, the popularization and the application, the security problem already became the electronic commerce development the bottleneck.This article embarked from the electronic commerce transaction process to the electronic commerce secure demand, introduced the digital signature principle, emphatically introduced the RSA encryption algorithm principle of work and its in the electronic commerce application.Keywords RSA;Encryption algorithm;electronic business

一、引言

随着经济的迅猛发展和网络技术的大范围的普及和应用,一种新兴的商务运作模式——电子商务,已经日趋成熟和完善。越来越多的人把上网作为自己获取信息的首要途径。目前在网上进行贸易的企业和个人日益增多,除了网上购物,还有网上商品销售、网上拍卖、网上货币支付等,人们的消费和生活习惯已经在慢慢改变,但与此同时,交易的风险性和不确定性也大大增加,安全问题已经成为电子商务发展的瓶预。

电子商务是建立在一个较为开放的网络环境上的,由于数据输入时的意外差错或欺诈行为,或数据传输过程中信息丢失、重复或传送次序差异等原因,贸易各方的信息有可能不同。这会导致纠纷的产生,甚至使交易无法进行。因此,要预防对信息的随意生成、修改和删除,同时要防止信息在传输过程中被非法窃取。鉴于此,电子商务活动中的信息及其传播的技术,不仅涉及到信息的制造和传输技术,同时还涉及到数据加密、身份认证和电子签名等技术。目前增强电子商务的安全方法很多,从网络系统到具体应用系统提出了多种方案、规范及加密体系,我们主要来探讨一下RSA加密算法。

二、数字签名的原理

数字签名的过程指报文发送方将报文文本带入哈希函数生成一个128位的数列值,即消息摘要,消息摘要代表文件的特征,其值随着文件的变化而变化,也就是说,不同的文件得到不同的消息摘要。哈希函数对于发送数据的双方都是公开的。发送方用自己的专用密钥对这个散列值进行加密,形成发送方的数字签名。然后,这个数字签名将作业报文的附件和报文一起发送给报文的接收方。报文的接收方首先从收到的原始报文中计算出128位的散列值(消息摘要),接着再用发送方的公开密钥来对报文附加的数字签名进行解密。如果两个散列值相同,那么接收方就能够确认数字签名是发送方的。通过数字签名能够实现对原始报文的鉴别和不可否认性。

从数字签名的过程可以看出,数字签名应当满足下列要求:接收方能够确认或证实发送方的签名,但不能伪造。发送方发出签名的消息给接收方后,就不能再否认所签发的消息。接收方对收到的签名消息不可否认,即有收报认证。

为了实现数字签名的目的,发送方需要向接收方提供足够的非保密信息,以便使其能够验证消息的签名,但又不能泄露用于产生签名的机密信息,以防他人伪造签名,因此,可用RSA签名机制来实现数字签名。

三、RSA加密算法的实现

RSA算法于1977年由美国麻省理工学院MIT(Massachusetts Institute of Technology)的Ronal Rivest,Adi Shamir和Len Adleman三位年轻教授提出,并以三人的姓氏Rivest,Shamir和Adlernan命名为RSA算法。该算法利用了数论领域的一个事实,那就是虽然把两个大质数相乘生成一个合数是件十分容易的事情,但要把一个合数分解为两个质数却十分困难。合数分解问题目前仍然是数学领域尚未解决的一大难题,至今没有任何高效的分解方法。与Diffie-Hellman算法相比,RSA算法具有明显的优越性,因为它无须收发双方同时参与加密过程,且非常适合于电子函件系统的加密。

RSA公共密钥加密算法的核心是欧拉(Euler)函数ψ。对于正整数n,ψ(n)定义为小于n且与n互质的正整数的个数。例如ψ(6)= 2,这是因为小于6且与6互质的数有1和5共两个数;再如ψ(7)= 6,这是因为互质数有1,2,3,5,6共6个。

欧拉在公元前300多年就发现了ψ函数的一个十分有趣的性质,那就是对于任意小于n且与n互质的正整数m,总有m

ψ(n)

mod n = 1。例如,5ψ(6)

mod 6 = 5 mod 6= 25 mod 6 =1。也就是说,在对n求余的运算下,ψ(n)指数具有周期性。

当n很小时,计算ψ(n)并不难,使用穷举法即可求出;但当n很大时,计算ψ(n)就十分困难了,其运算量与判断n是否为质数的情况相当。不过在特殊情况下,利用ψ函数的两个性质,可以极大地减少运算量。

性质1:如果p是质数,则ψ(p)=(p-1)。

性质2:如果p与q均为质数,则ψ(p·q)= ψ(p)·ψ(q)=(p-1)(q-1)。

RSA算法正是注意到这两条性质来设计公共密钥加密系统的,p与q的乘积n可以作为公共密钥公布出来,而n的因子p和q则包含在专用密钥中,可以用来解密。如果解密需要用到ψ(n),收信方由于知道因子p和q,可以方便地算出ψ(n)=(p-1)(q-1)。如果窃听者窃得了n,但由于不知道它的因子p与q,则很难求出ψ(n)。这时,窃听者要么强行算出ψ(n),要么对n进行因数分解求得p与q。然而,我们知道,在大数范围内作合数分解是十分困难的,因此窃密者很难成功。

2四、RSA加密算法的工作原理

有了关于ψ函数的认识,我们再来分析RSA算法的工作原理:

1、密钥配制。设m是要加密的信息,任选两个大质数p与q,选择正整数e,使得e与ψ(n)=(p-1)(q-1)互质。

利用辗转相除法,计算d,使得ed mod ψ(n)=1,即ed = kψ(n)+1,其中k为某一正整数。

公共密钥为(e,n),其中没有包含任何有关n的因子p和q的信息。专用密钥为(d,n),其中d隐含有因子p和q的信息。

2、加密过程。将明文m(其值的范围在0到n-1之间)按模为n自乘e次

e幂以完成加密操作,c=m(mod n),得密文c。

3、解密过程。使用(d,n)对密文c进行解密,将密文c按模为n自乘d次幂,完成解密操作m=c(mod n)计算过程为:

c mod n =(m mod n)mod n = m mod n = m(kψ(n)+ 1)kψ(n)edd

e

d

d

mod n =(m mod n)·(m mod n)

= m m即为从密文c中恢复出来的明文。

例如,假设我们需要加密的明文代码信息为m = 14,则: 选择e = 3,p = 5,q = 11; 计算出n = p·q = 55,(p-1)(q-1)= 40,d = 27; 可以验证:(e·d)mod(p-1)(q-1)= 81 mod 40 = 1; 加密:c = m mod n = 14 mod 55 = 49; 解密:m = c mod n = 49 mod 55 = 14。

关于RSA算法,还有几点需要进一步说明:

1、之所以要求e与(p-1)(q-1)互质,是为了保证 ed mod(p-1)(q-1)有解。

2、实际操作时,通常先选定e,再找出并确定质数p和q,使得计算出d后它们能满足公式(12-3)。常用的e有3和65537,这两个数都是费马序列中的数。费马序列是以17世纪法国数学家费马命名的序列。

3、破密者主要通过将n分解成p·q的办法来解密,不过目前还没有办法证明这是唯一的办法,也可能有更有效的方法,因为因数分解问题毕竟是一个不断发展的领域,自从RSA算法发明以来,人们已经发现了不少有效的因数分解方法,在一定程度上降低了破译RSA算法的难度,但至今还没有出现动摇RSA算法根基的方法。

4、在RSA算法中,n的长度是控制该算法可靠性的重要因素。目前129位、甚至155位的RSA加密勉强可解,但目前大多数加密程序均采用231、308甚至616位的RSA算法,因此RSA加密还是相当安全的。d

27e

3五、结束语

据专家测算,攻破512位密钥RSA算法大约需要8个月时间;而一个768位密钥RSA算法在1年之内无法攻破。现在,在技术上还无法预测攻破具有2048位密钥的RSA加密算法需要多少时间。美国Lotus公司悬赏1亿美元,奖励能破译其Domino产品中1024位密钥的RSA算法的人。从这个意义上说,遵照SET协议开发的电子商务系统是绝对安全的。

利用前面讲解的加密方法,尤其是基于双钥技术的现代加密方法,我们针对网络安全可以实现多种具体的手段及方法,如数字签名、数字时间戳、数字凭证及认证中心等,而且这些方法和手段常常结合在一起使用,长短互补,从而构成了网上安全防范的实用体系。

参考文献

[1]王茜,杨德礼.电子商务的安全体系结构及技术研究[J],计算机工程,2004年

[2]朱文余.计算机密码应用基础,科学出版社,2005年

[3]陈风,张利萍.RAS算法及其在电子商务中的应用[ J] .铁路训算机应用,2005 [4]倪春胜.数字签名技术在电子商务中的应用[J] .计算机工程与应用,2006

第五篇:RSA加密解密算法c语言程序

#include

#include

#include

//将十进制数转换成二进制,用于检验大素数p和q int zhuan_huan(int b,int a[],int k)

{ int t,temp=-1;

while(b>0){

t=b%2;

temp++;

a[temp]=t;

b=b/2;

}

return temp;

}

//欧几里得算法,用于判断加密指数e是否符合要求 int gcd(int n,int b)

{

int r1=n,r2=b,r;

while(r2>0){

r=r1%r2;

r1=r2;

r2=r;

}

return r1;

}

//扩展欧几里得算法求乘法逆元,即求解密指数d int extend(int n,int b)

{

int q,r,r1=n,r2=b,t,t1=0,t2=1,i=1;

while(r2>0)

{

q=r1/r2;

r=r1%r2;

r1=r2;r2=r;

t=t1-q*t2;

t1=t2;

t2=t;

}

if(t1>=0)return t1%n;

else{

while((t1+i*n)<0)

i++;

return t1+i*n;

}

}

//检验大素数,符合要求返回1,否则返回0

int Witness(int a,int n)

{

int d=1,k,r=n-1,i,x,b[1000];

k=zhuan_huan(r,b,1000);

for(i=k;i>=0;i--){

x=d;

d=(d*d)%n;

if((d==1)&&(x!=1)&&(x!=n-1))return 0;

if(b[i]==1)d=(d*a)%n;

}

if(d!=1)return 0;

else return 1;

}

//快速计算模指数

int js_mod(int a,int b,int n)

{

int x=0,y=1,k,i,s[1000];

k=zhuan_huan(b,s,1000);

for(i=k;i>=0;i--){

x=2*x;

y=(y*y)%n;

if(s[i]==1){

x++;

y=(y*a)%n;

}

}

return y;

}

//主函数。。。。。。。。。。。。。。。。。。。。。。

void main()

{

int p,q,e,d,n,yn,m[1000],c[10000];//c[10000]存放加密后的数字密文,m[1000]存放解密后的数字明文,即英文明文在zimu_biao[69]中的下标。

int i,j;//i,j用于循环遍历数组

int mi_yue;//用户输入的密钥

int count=1;//统计输入密钥的次数,count>3时将不允许用户再输入。

char min_wen[1000],re_min_wen[1000];//分别为用户输入的明文、密文,解密后的明文。//密钥生成char

zimu_biao[69]=“abcdefghijklmnopqrstuvwxyz,ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789'.?!”;

printf(“请输入您要发送的明文文件(小写英文表示):n”);

printf(“******************************************************n”);

gets(min_wen);

printf(“******************************************************n”);

printf(“n加密开始,请按要求操作。。nn”);

printf(“请输入第一个大素数p:n”);

while(1){

scanf(“%d”,&p);

if(Witness(2,p)==1){

printf(“您输入的第一个大素数 %d 符合要求n”,p);

break;

}

else

printf(“您输入的 %d 不是素数,请重新输入:n”,p);

}

printf(“请输入第二个大素数q:n”);

while(1){

scanf(“%d”,&q);

if(Witness(2,q)){

printf(“您输入的第二个大素数 %d 符合要求n”,q);

break;

}

else

printf(“您输入的 %d 不是素数,请重新输入:n”,q);

}

n=p*q;yn=(p-1)*(q-1);

printf(“请输入加密指数(整数)e,且0

scanf(“%d”,&e);

if(gcd(yn,e)==1){

printf(“您输入加密指数 %d 与 %d 互素,符合要求n”,e,yn);

break;

}

else

printf(“您输入加密指数 %d 与 %d 不互素,请重新输入。。n”,e,yn);

}

d=extend(yn,e);//求解密指数d

printf(“nn请记住您的两个大素数分别为p=%d(保密),q=%d(保密),模数n=%d(公开),欧拉函数yn=%d(保密),加密指数e=%d(公钥,公开),。。解密指数 d=%d(私钥,保密)nn”,p,q,n,yn,e,d);

//明文转换过程

/* scanf(“%s”,min_wen);

printf(“%s”,min_wen);*/

for(i=0;i

for(j=0;j<68;j++)//for(j=0;j<26;j++)

if(min_wen[i]==zimu_biao[j])

m[i]=j;//将字符串明文换成数字,并存到整型数组m里面,即明文的另一种表示方法

//加密过程

for(i=0;i

c[i]=js_mod(m[i],e,n);

printf(“输出密文:n”);

printf(“******************************************************n”);

for(i=0;i

printf(“%d”,c[i]);

printf(“n******************************************************n”);

//解密过程

for(i=0;i

m[i]=js_mod(c[i],d,n);

for(i=0;i

re_min_wen[i]=zimu_biao[m[i]];

//提示用户解密

printf(“nn您有3次输入密钥的机会,密钥正确后将进行解密显示明文,3次输入错误解密将终止,请注意。。nn”);

while(1){

scanf(“%d”,&mi_yue);

if(mi_yue==d){

printf(“密钥输入正确,您得到的明文为:nn”);

for(i=0;i

printf(“%c”,re_min_wen[i]);

printf(“nn”);

break;

}

else{

}} }}printf(“您第%d次输入的密钥错误,请重新输入。。n”,count);count++;if(count>3){printf(“n您已%d次输入的密钥错误,将不允许继续输入n”,count-1);break;

下载RSA实验报告word格式文档
下载RSA实验报告.doc
将本文档下载到自己电脑,方便修改和收藏,请勿使用迅雷等下载。
点此处下载文档

文档为doc格式


声明:本文内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:645879355@qq.com 进行举报,并提供相关证据,工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。

相关范文推荐

    RSA合理自我分析报告(写写帮整理)

    RSA合理自我分析报告(案例) (一) 事件(A):我考试没有考第一名。 情绪(C):头痛,入睡困难,焦虑不安,无法上课,很痛苦。 信念(B):我必须考第一名,只有考第一名大家才不会失望,中考才能考好,只有考上......

    实验报告

    实验报告 固体碱催化剂KF/CaO-MgO-Fe3O4的制备与表征 摘要:采用在制备复合物CaO—MgO的过程中加入一定量磁性基质Fe3O4来制备磁性复合物CaO—MgO—Fe3O4,再以等体积浸渍法负载......

    实验报告

    技 能 训 练 实习报 告 学院:经济与管理 班级:09人力2班 学号:0868100136 姓名:苏日古嘎 一、 实验名称:奥派人力资源实践平台 二、 实验目的: 奥派人力资源实践平台系统按......

    实验报告

    一、实验目的和要求 1、通过实验使学生掌握拟进行的会计模拟实验的基本情况,在接下来的会计模拟实验中,有明确的前提条件。知道所应遵循的规则和方法以及在会计模拟操作过程中......

    实验报告

    第次作业 电子科技大学计算机科学与工程学院实验报告(实验)课程名称信息安全基础综合设计实验电子科技大学实验报告 学生姓名:杨川 指导教师:丁熠 实验地点:主楼 A2-413实验项目......

    实验报告

    _______课程实验报告 实验名称 系 别 姓 名 学 号 班 级 实验地点 实验日期 评 分 指导老师 同组其他成员 一、实验内容(含实验原理介绍): 二、实验目的 第一范文 网整理该文......

    实验报告

    姓名:学号: 试验XXXXXXXXXXXX 一、试验目的 . . .....二、实验设备 三、试验内容 所做具体实验的概括四、实验步骤(重点写) 怎么做的实验,就按步骤顺序往下写,并附贴图 五、实验中......

    实验报告

    “XXXXXX”案(刑事/民事/行政)诉讼(代理/辩护) 实验报告 学生姓名:教 学 点:完成时间:班级学号:指导教师:报告成绩:报告得分以100分制记,实验报告全文要求在2000字以上,字数不到者,不能得......