您的位置:首页 > 其它

第二次作业(RSA)

2014-03-20 01:52 621 查看
RSA:RSA公钥系统发明于新思想提出后一年在麻省理工学院,里维斯特(Ronald
Rivest)、沙米尔(Adi Shamir)和阿德勒曼(Len
Adleman)提出第一个较完善的公钥密码体制——RSA体制,由三位发明人的姓氏首字母命名。这是一种建立在大数因子分解基础上的算法。它是第一个成熟的、迄今为止理论上最成功的公钥密码体制。它的安全性是基于数论中的大整数因子分解。该问题是数论中的一个困难问题,至今没有有效的算法,(即大整数因子分解不能在多项式时间内完成)这使得该体制具有较高的保密性。并且得到了广泛应用。不为人知的是,早在1970年的秘密研究中,英国情报机构GCHQ的数学家James
H. Ellis便已发明非对称钥匙密码学,而且Diffie-Hellman与RSA都曾被Malcolm
J. Williamson与Clifford Cocks分别发明于前。这两个最早的公钥系统提供优良的加密法基础,因而被大量使用。其他公钥系统还有Cramer-Shoup、Elgamal、以及椭圆曲线密码学等等。这些事件直到1997年历史文件解密的时候才为大众所知。

数字签名:

数字签名,就是只有信息的发送者才能产生的别人无法伪造的一段数字串,这段数字串同时也是对信息的发送者发送信息真实性的一个有效证明。

数字签名是非对称密钥加密技术数字摘要技术的应用。

数字签名了的文件的完整性是很容易验证的(不需要骑缝章,骑缝签名,也不需要笔迹专家),而且数字签名具有不可抵赖性(不需要笔迹专家来验证)。

简单地说,所谓数字签名就是附加在数据单元上的一些数据,或是对数据单元所作的密码变换。这种数据或变换允许数据单元的接收者用以确认数据单元的来源和数据单元的完整性并保护数据,防止被人(例如接收者)进行伪造。它是对电子形式的消息进行签名的一种方法,一个签名消息能在一个通信网络中传输。基于公钥密码体制私钥密码体制都可以获得数字签名,主要是基于公钥密码体制的数字签名。包括普通数字签名和特殊数字签名。普通数字签名算法有RSA、ElGamal、Fiat-Shamir、Guillou-
Quisquarter、Schnorr、Ong-Schnorr-Shamir数字签名算法、Des/DSA,椭圆曲线数字签名算法和有限自动机数字签名算法等。特殊数字签名有盲签名、代理签名、群签名、不可否认签名、公平盲签名、门限签名、具有消息恢复功能的签名等,它与具体应用环境密切相关。显然,数字签名的应用涉及到法律问题,美国联邦政府基于有限域上的离散对数问题制定了自己的数字签名标准(DSS)。

公钥:公钥是与私钥算法一起使用的密钥对的非秘密一半。公钥通常用于加密会话密钥、验证数字签名,或加密可以用相应的私钥解密的数据。公钥和私钥是通过一种算法得到的一个密钥对(即一个公钥和一个私钥)其中的一个向外界公开,称为公钥;另一个自己保留,称为私钥。通过这种算法得到的密钥对能保证在世界范围内是唯一的。使用这个密钥对的时候,如果用其中一个密钥加密一段数据,必须用另一个密钥解密。比如用公钥加密数据就必须用私钥解密,如果用私钥加密也必须用公钥解密,否则解密将不会成功。

DES:数据加密算法(Data
Encryption Algorithm,DEA)是一种对称加密算法,很可能是使用最广泛的密钥系统,特别是在保护金融数据的安全中,最初开发的DEA是嵌入硬件中的。通常,自动取款机(Automated Teller Machine,ATM)都使用DEA。它出自IBM的研究工作,IBM也曾对它拥有几年的专利权,但是在1983年已到期后,处于公有范围中,允许在特定条件下可以免除专利使用费而使用。1977年被美国政府正式采纳。

公钥加密与数字签名之间的关系:根据非对称密码学的原理,每个证书持有人都有一对公钥和私钥,这两把密钥可以互为加解密。公钥加密使用一个必须对未经授权的用户保密的私钥和一个可以对任何人公开的公钥。公钥和私钥都在数学上相关联;用公钥加密的数据只能用私钥解密,而用私钥签名的数据只能用公钥验证。公钥可以被任何人使用;该密钥用于加密要发送到私钥持有者的数据。两个密钥对于通信会话都是唯一的。公钥加密算法也称为不对称算法,原因是需要用一个密钥加密数据而需要用另一个密钥来解密数据。数字证书则是由证书认证机构(CA)对证书申请者真实身份验证之后,用CA的根证书对申请人的一些基本信息以及申请人的公钥进行签名(相当于加盖发证书机构的公章)后形成的一个数字文件。CA完成签发证书后,会将证书发布在CA的证书库(目录服务器)中,任何人都可以查询和下载,因此数字证书和公钥一样是公开的。可以这样说,数字证书就是经过CA认证过的公钥,而私钥一般情况都是由证书持有者在自己本地生成的,由证书持有者自己负责保管。具体使用时,签名操作是发送方用私钥进行签名,接受方用发送方证书来验证签名;加密操作则是用接受方的证书进行加密,接受方用自己的私钥进行解密。
因此,如果说数字证书是电子商务应用者的网上数字身份证话,那么证书相应的私钥则可以说是用户的私章或公章。公钥算法还可用于构成数字签名。数字签名验证发送方的标识(如果您信任发送方的公钥)并保护数据的完整性。

 实现RSA算法(书籍P40)。同学们至少实现2.1
与 2.2;实现RSA完整算法的同学,总成绩的基础上加10分。请大家把编程思想与程序实现(源码),发表在CSDN博文上。

1: 判断一个正整数是否为质数的算法。函数签名如下

     int isPrime(long a)

    输入:一个长整数a

    输出:返回1(为质数),返回0(非质数)

程序如下:

import java.util.Scanner;

public class Demo02
{
/**
* 判断一个正整数是否为质数的算法
*/
public static void main(String[] args)
{
System.out.print("请输入一个正整数:");
Scanner scanner=new Scanner(System.in);
long num=scanner.nextLong();
int result= isPrime(num);
if(result==1){
System.out.println(num+"是质数");
}else{
System.out.println(num+"不是质数!");
}
}
public static  int isPrime(long a){
if(a==1){
return 1;
}
for(int i=2;i<Math.sqrt(a);i++){
if(a%i==0){
return 0;
}
}
return 1;
}
}




2: 随机生成一个n bit位的长整数。函数签名如下

    long createRndInteger(int n)

    输入:随机数bit位的长度为n(解释:3bit位,则最大为111,最小为100;n bit位,则该数字二进制长度为n)

    输出:返回该随机数

程序如下:

import java.util.Random;
import java.util.Scanner;

public class Demo02 {

/**
* 随机生成一个n bit位的长整数
*/
public static void main(String[] args) {
System.out.print("请输入随机生成n bit位的长整数的长度:");
Scanner scanner=new Scanner(System.in);
int num= scanner.nextInt();
long random= createRndInteger(num);
System.out.println("随机生成的"+num+"bit位的长整数是:"+random);
}

public static  long createRndInteger(int n){
int[] a={0,1};
StringBuilder sb=new StringBuilder();
Random random=new Random();
if(n==1){
return a[random.nextInt(a.length)];
}else{
sb.append(1);
for(int i=0;i<n-1;i++){
sb.append(a[random.nextInt(a.length)]);
}
System.out.println("随机生成的"+n+"bit位的二进制数是:"+sb.toString());
long num=Long.parseLong(sb.toString(),2);

return num;
}
}
}




3:随机生成一个n bit位的长质数。函数前面如下

    long createRndPrime(int n)

    输入:随机质数的bit位长度为n

    输出:nbit位长度的质数

    关键为使用随机化算法判断一个长整数是否为素数(P33)。
程序如下:

import java.util.Random;
import java.util.Scanner;

public class Demo02 {

public static void main(String[] args) {
System.out.print("请输入随机生成n bit位:");

Scanner scanner=new Scanner(System.in);
int num= scanner.nextInt();
while(true){
long random= createRndInteger(num);
int result=isPrime(random);
if(result==1){
System.out.println("随机生成的"+num+"bit位的长质数是:"+random);
break;
}else{
System.out.println("生成的不是质数");
}
}

}

public static long createRndInteger(int n){
int[] a={0,1};
StringBuilder sb=new StringBuilder();
Random random=new Random();
if(n==1){
return a[random.nextInt(a.length)];
}else{
sb.append(1);
for(int i=0;i<n-1;i++){
sb.append(a[random.nextInt(a.length)]);
}
System.out.println("随机生成的"+n+"bit位的二进制数是:"+sb.toString());
long num=Long.parseLong(sb.toString(),2);

return num;
}
}
public static int isPrime(long a){
if(a==1){
return 1;
}
for(int i=2;i<Math.sqrt(a);i++){
if(a%i==0){
return 0;
}
}
return 1;
}
}




4.公开密钥(N,e)的生成算法。 关键为怎样选择一个与(p-1)(q-1)互质的数e。

程序如下:

import java.util.Random;
import java.util.Scanner;
/**
* 公开密钥(N,e)的生成算法。 关键为怎样选择一个与(p-1)(q-1)互质的数e。
* @author Administrator
*
*/
public class Demo02 {

public static void main(String[] args) {
System.out.print("请输入随机生成n bit位:");
Scanner scanner=new Scanner(System.in);
int num= scanner.nextInt();
if(num<=1){
System.out.print("请输入更多位:");
}
long p=createRndInteger(num);
System.out.println("生成的第1个质数:"+p);
long q=0;
do{
q=createRndInteger(num);
}while(p==q);
System.out.println("生成的第2个质数:"+q);
long n=p*q;
long t=(p-1)*(q-1);
int e=0;
for(int i=2;i<t;i++){
if(t%i!=0){
e=i;
break;
}
}
System.out.println("产生的公开密钥(N,e)=("+n+","+e+")");
}
public static long createRndInteger(int n){
long num=0;
while(true){
int[] a={0,1};
StringBuilder sb=new StringBuilder();
Random random=new Random();
sb.append(1);
for(int i=0;i<n-1;i++){
sb.append(a[random.nextInt(a.length)]);
}
num=Long.parseLong(sb.toString(),2);
int result= isPrime(num);
if(result==1){

break;
}else{
System.out.println("随机生成的不是质数.");
}
}
return num;
}
public static int isPrime(long a){
if(a==1){
return 1;
}
for(int i=2;i<Math.sqrt(a);i++){
if(a%i==0){
return 0;
}
}
return 1;
}
}



5:保密密钥(N,d)的生成算法。关键是运用扩展Euclid算法,生成e模(p-1)(q-1)的逆元,见书籍25页。

程序如下:

import java.util.Random;
import java.util.Scanner;

public class Demo02 {

/**
* 保密密钥(N,d)的生成算法。关键是运用扩展Euclid算法,生成e模(p-1)(q-1)的逆元,见书籍25页。
*/
public static void main(String[] args) {
System.out.print("请输入随机生成n bit位");
Scanner scanner=new Scanner(System.in);
int num= scanner.nextInt();
if(num<=1){
System.out.print("输入的bit位不能太短.:");
}
long p=createRndInteger(num);
System.out.println("生成的第1个质数:"+p);
long q=0;
do{
q=createRndInteger(num);
}while(p==q);
System.out.println("生成的第2个质数:"+q);
long n=p*q;
long t=(p-1)*(q-1);
int e=0;
for(int i=2;i<t;i++){
if(t%i!=0){
e=i;
break;
}
}
System.out.println("产生的公开密钥(N,e)=("+n+","+e+")"+t);
int d=0;
for(int i=1;i<t;i++){
if(e*i%t==1){
d=i;
break;
}
}
System.out.println("生成的密钥(N,d)=("+n+","+d+")");
}

public static long createRndInteger(int n){
long num=0;
while(true){
int[] a={0,1};
StringBuilder sb=new StringBuilder();
Random random=new Random();
sb.append(1);
for(int i=0;i<n-1;i++){
sb.append(a[random.nextInt(a.length)]);
}
num=Long.parseLong(sb.toString(),2);
int result= isPrime(num);
if(result==1){

break;
}else{
System.out.println("随机生成的不是质数,");
}
}
return num;
}
public static int isPrime(long a){
if(a==1){
return 1;
}
for(int i=2;i<Math.sqrt(a);i++){
if(a%i==0){
return 0;
}
}
return 1;
}
}




6:RSA加密算法。对消息m=25进行加密,生成密文c。

程序如下:

import java.util.Random;
import java.util.Scanner;

public class Demo02 {

/**
* RSA加密算法。对消息m=25进行加密,生成密文c。
*/
public static void main(String[] args) {
System.out.print("请输入随机生成n bit位:");
Scanner scanner=new Scanner(System.in);
int num= scanner.nextInt();
if(num<=1){
System.out.print("输入的bit位太短.");
}
long p=createRndInteger(num);
System.out.println("生成的第1个质数:"+p);
long q=0;
do{
q=createRndInteger(num);
}while(p==q);
System.out.println("生成的第2个质数:"+q);
long n=p*q;
long t=(p-1)*(q-1);
long e=public_key(num,t);//产生公钥
System.out.println("产生的公开密钥(N,e)=("+n+","+e+")");
long d=private_key(num,t,e);//长生私钥
System.out.println("产生的私钥(N,d)=("+n+","+d+")");
System.out.print("请输入明文:");
long m= scanner.nextLong();
long c=encoder(m,e,n);
System.out.println("产生的密文是:"+c);

}
/**
* 进行加密
* @return
*/
public static long encoder(long m,long e,long n){
long f = 1;
for(int i=1;i<=e;i++){
f=f*m;
}
long c=f%n;//产生密文
return c;
}

/**
* 产生公钥
* @return
*/
public static long public_key(long num,long t){
int e=0;
for(int i=2;i<t;i++){
if(t%i!=0){ e=i; break;
}
}
return e;
}
/**
* 产生私钥
* @return
*/
public static long private_key(long num,long t,long e){
int d=0;
for(int i=1;i<t;i++){
if(e*i%t==1){ d=i; break;
}
}
return d;
}
public static long createRndInteger(int n){
long num=0;
while(true){
int[] a={0,1};
StringBuilder sb=new StringBuilder();
Random random=new Random();
sb.append(1);
for(int i=0;i<n-1;i++){
sb.append(a[random.nextInt(a.length)]);
}
num=Long.parseLong(sb.toString(),2);
int result= isPrime(num);
if(result==1){break;}
else{System.out.println("随机生成的不是质数,");}
}
return num;
}
public static int isPrime(long a){
if(a==1){return 1;}
for(int i=2;i<Math.sqrt(a);i++){
if(a%i==0){
return 0;
}
}
return 1;
}
}




7:RSA解密算法。对密文c进行解密。

程序如下:

import java.util.Random;
import java.util.Scanner;

public class Demo02 {

/**
* 保密密钥(N,d)的生成算法。关键是运用扩展Euclid算法,生成e模(p-1)(q-1)的逆元,见书籍25页。
*/
public static void main(String[] args) {
System.out.print("请输入随机生成n bit位:");
Scanner scanner=new Scanner(System.in);
int num= scanner.nextInt();
if(num<=1){
System.out.print("输入的bit位太短.");
}
long p=createRndInteger(num);
System.out.println("生成的第1个质数:"+p);
long q=0;
do{
q=createRndInteger(num);
}while(p==q);
System.out.println("生成的第2个质数:"+q);
long n=p*q;
long t=(p-1)*(q-1);
long e=public_key(t);//产生公钥
System.out.println("产生的公开密钥(N,e)=("+n+","+e+")");
long d=private_key(t,e);//长生私钥
System.out.println("产生的私钥(N,d)=("+n+","+d+")");
System.out.print("请输入明文:");
long m= scanner.nextLong();
long c=encoder(m,e,n);
System.out.println("产生的密文是:"+c);
m= decoder(c,d,n);
System.out.println("解密之后是:"+m);
}
/**
*
* 进行解密
*/
public static long decoder(long c,long d,long n){
long j=1,m=1;
for(int i=1;i<=d;i++){
j=j*c;
}
m=j%n;
return m;
}
/**
* 进行加密
* @return
*/
public static long encoder(long m,long e,long n){
long f = 1,c=1;
for(int i=1;i<=e;i++){
f=f*m;
}
c=f%n;//产生密文
return c;
}

public static long public_key(long t){
int e=0;
for(int i=2;i<t;i++){
if(t%i!=0){
e=i;
break;
}
}
return e;
}
public static long private_key(long t,long e){
int d=1;
for(int i=1;i<t;i++){
if(e*i%t==1){
d=i;
break;
}
}
return d;
}
public static long createRndInteger(int n){
long num=0;
while(true){
int[] a={0,1};
StringBuilder sb=new StringBuilder();
Random random=new Random();
sb.append(1);
for(int i=0;i<n-1;i++){
sb.append(a[random.nextInt(a.length)]);
}
num=Long.parseLong(sb.toString(),2);
int result= isPrime(num);
if(result==1){
break;
}else{
System.out.println("随机生成的不是质数.");
}
}
return num;
}
public static int isPrime(long a){
if(a==1){
return 1;
}
for(int i=2;i<Math.sqrt(a);i++){
if(a%i==0){
return 0;
}
}
return 1;
}
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  算法 rsa