教学服务系统

 找回密码
 立即注册
搜索
查看: 575|回复: 1

信息计算2019级2班6号李靓

[复制链接]

8

主题

17

帖子

72

积分

注册会员

Rank: 2

积分
72
发表于 2022-5-31 11:29:10 | 显示全部楼层 |阅读模式
本帖最后由 李靓 于 2022-5-31 11:34 编辑

RSA加密、解密以及签名

1.RSA加解密

秘钥生成:选择两个互异的大素数,二者保密。计算,公开保密,选择一个公开的随机数,满足,计算保密。此时,公钥为,私钥为
加密:加密结果,已知条件,公钥
解密:解密结果,已知条件,私钥

2.RSA签名验签
选取整数,消息空间与签名空间均为整数空间,即,定义秘钥集合
,Bob要对签名,取,于是验证等式是否成立。

3.源代码
  1. package InformationScience;

  2. import java.security.*;
  3. import java.security.spec.InvalidKeySpecException;
  4. import java.security.spec.PKCS8EncodedKeySpec;
  5. import java.security.spec.X509EncodedKeySpec;
  6. import java.util.Base64;

  7. /**
  8. * @ClassName TestSignature
  9. * @Author king
  10. * @Date 2020/3/27 10:09
  11. * @Version V1.0
  12. **/
  13. public class TestSignature {
  14.     public static void main(String[] args) throws Exception {
  15.         KeyPair keyPair = generateKeyPair();
  16.         String privateKey = Base64.getEncoder().encodeToString(keyPair.getPrivate().getEncoded());
  17.         String publicKey = Base64.getEncoder().encodeToString(keyPair.getPublic().getEncoded());

  18.         String data = "data will be signature";
  19.         String signatureData = signature(data, privateKey);
  20.         boolean verify = verify(signatureData, data, publicKey);
  21.         System.out.println(verify);

  22.     }

  23.     /**
  24.      * @return java.security.KeyPair
  25.      * @Description 生成秘钥对
  26.      * @Date 2020/3/27 10:12
  27.      **/
  28.     public static KeyPair generateKeyPair() throws NoSuchAlgorithmException {
  29.         KeyPairGenerator rsa = KeyPairGenerator.getInstance("RSA");
  30.         rsa.initialize(2048);
  31.         return rsa.generateKeyPair();
  32.     }

  33.     /**
  34.      * @return String
  35.      * @Author wangwei
  36.      * @Description 加签
  37.      * @Date 2020/3/27 10:18
  38.      **/
  39.     public static String signature(String data, String privateKey) throws Exception {
  40.         Signature signature = Signature.getInstance("MD5withRSA");
  41.         signature.initSign(generatePrivateKey(privateKey));
  42.         signature.update(data.getBytes());
  43.         byte[] sign = signature.sign();
  44.         return Base64.getEncoder().encodeToString(sign);
  45.     }

  46.     /**
  47.      * @return java.security.PrivateKey
  48.      * @Description 根据String生成privateKey
  49.      * @Date 2020/3/27 10:30
  50.      * @Param [string]
  51.      **/
  52.     public static PrivateKey generatePrivateKey(String string) throws NoSuchAlgorithmException, InvalidKeySpecException {
  53.         KeyFactory keyFactory = KeyFactory.getInstance("RSA");
  54.         byte[] decode = Base64.getDecoder().decode(string.getBytes());
  55.         PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(decode);
  56.         return keyFactory.generatePrivate(pkcs8EncodedKeySpec);
  57.     }

  58.     /**
  59.      * @return java.security.PublicKey
  60.      * @Description 根据String生成PublicKey
  61.      * @Date 2020/3/27 10:42
  62.      * @Param [string]
  63.      **/
  64.     public static PublicKey generatePublicKey(String string) throws NoSuchAlgorithmException, InvalidKeySpecException {
  65.         KeyFactory keyFactory = KeyFactory.getInstance("RSA");
  66.         byte[] decode = Base64.getDecoder().decode(string.getBytes());
  67.         X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(decode);
  68.         return keyFactory.generatePublic(x509EncodedKeySpec);
  69.     }

  70.     /**
  71.      * @return boolean
  72.      * @Description 校验数据是否正确
  73.      * @Date 2020/3/27 10:42
  74.      * @Param [signatureData, data, publicKey]
  75.      **/
  76.     public static boolean verify(String signatureData, String data, String publicKey) throws InvalidKeySpecException, NoSuchAlgorithmException, InvalidKeyException, SignatureException {
  77.         PublicKey publicKey1 = generatePublicKey(publicKey);
  78.         Signature signature = Signature.getInstance("MD5withRSA");
  79.         signature.initVerify(publicKey1);
  80.         signature.update(data.getBytes());
  81.         return signature.verify(Base64.getDecoder().decode(signatureData));

  82.     }
  83. }

复制代码

4.运行结果:








本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

8

主题

17

帖子

72

积分

注册会员

Rank: 2

积分
72
 楼主| 发表于 2022-5-31 14:47:59 | 显示全部楼层
本帖最后由 李靓 于 2022-5-31 14:51 编辑

ECC椭圆曲线上公钥密码

1.ECC公私钥对生成
(1)选择一个椭圆曲线 E:y2 =x3 +ax+b(mod p), 构造一个椭圆群Ep(a ,b)
(2)在Ep(a,b) 中挑选生成元点G=(x1 ,y1) ,G 应使得满足nG = O 的最小的n 是一个非常大的素数.
(3)选择一个小于n 的整数nA 作为其 私钥 ,然后产生其 公钥PA=nAG ;
注:公开的信息: (E,G,n,PA)
|Ep|表示椭圆群Ep(a,b)的元素个数,n是|Ep|的素因子 。


2.ECC加密算法
2.1发送方签名
1)选择一个随机的key kE 0<kE<n
2)计算 R = kE A
3)令 r ≡ x R (mod p) ,即 r为R的x坐标对p求模
4)计算 s ≡ ( h ( x ) + d ⋅ r ) k E^ − 1 ( mod q)
则生成的 ( r , s ) 就是数字签名。之后发送方将 (s,(r, s)) 发送给接收方


2.2接收方验证
1)计算 u 1 ≡ s^−1⋅h(x)(mod q)
2)计算 u 2 ≡ s−1⋅r(mod q)
3)计算 P = u 1 A + u 2 B
4)进行验证
x P = {≡ r (mod q ) → 签 名 有 效
/≡ r (mod q) → 签 名 无 效
}
这里的− 1 表示在模运算中求逆,在Zp中,一个数a与它的逆 a^−1满足 a⋅a−1≡1(mod p)


3.源代码
  1. #include <stdio.h>
  2. #include <math.h>
  3. int xy[22];

  4. #define N 23
  5. #define A 1
  6. //#define M 29
  7. #define a1 1
  8. #define b1 4
  9. typedef struct point{
  10.         int x;
  11.         int y;
  12. }Point;
  13. typedef struct ecc{
  14.         struct point p[100];
  15.         int len;
  16. }ECCPoint;
  17. typedef struct generator{
  18.         Point p;
  19.         int p_class;
  20. }GENE_SET;
  21. ECCPoint eccPoint;
  22. Point mul(Point p1,Point p2);
  23. Point add_two_points(Point p1,Point p2);
  24. GENE_SET geneSet[100];
  25. int geneLen;
  26. //判断平方根是否为整数
  27. int int_sqrt(int s)
  28. {
  29.         int temp;
  30.         temp=(int)sqrt(s);//转为整型
  31.         if(temp*temp==s)
  32.         {
  33.                 return temp;
  34.         }else{
  35.                 return -1;
  36.         }
  37. }
  38. //取模函数
  39. int mod_p(int s)
  40. {
  41.         int i;        //保存s/p的倍数
  42.         int result;        //模运算的结果
  43.         i = s / N;
  44.         result = s - i * N;
  45.         if (result >= 0)
  46.         {
  47.                 return result;
  48.         }
  49.         else
  50.         {
  51.                 return result + N;
  52.         }
  53. }
  54. //打印点集
  55. void print()
  56. {
  57.         int i;
  58.         int len=eccPoint.len;
  59.         printf("\n该椭圆曲线上共有%d个点(包含无穷远点)\n",len+1);
  60.         for(i=0;i<len;i++)
  61.         {
  62.                 if(i % 8==0)
  63.                 {
  64.                         printf("\n");
  65.                 }
  66.                 printf("(%2d,%2d)\t",eccPoint.p[i].x,eccPoint.p[i].y);
  67.         }
  68.         printf("\n");
  69. }
  70. //task1:求出椭圆曲线上所有点
  71. void get_all_points()
  72. {
  73.         int i=0;
  74.         int j=0;
  75.         int s,y=0;
  76.         int n=0,q=0;
  77.         int modsqrt=0;
  78.         int flag=0;
  79.         if ( a1 * a1 * a1 + b1 * b1+4 != 0)
  80.         {
  81.                 for(i=0;i<=N-1;i++)
  82.                 {
  83.                         flag=0;
  84.                         n=1;
  85.                         y=0;
  86.                         s= i * i * i + a1 * i + b1;
  87.                         while(s<0)
  88.                         {
  89.                                 s+=N;
  90.                         }
  91.                         s=mod_p(s);
  92.                         modsqrt=int_sqrt(s);
  93.                         if(modsqrt!=-1)
  94.                         {
  95.                                 flag=1;
  96.                                 y=modsqrt;
  97.                         }else{
  98.                                 while(n<=N-1)
  99.                                 {
  100.                                         q=s+n*N;
  101.                                         modsqrt=int_sqrt(q);
  102.                                         if(modsqrt!=-1)
  103.                                         {
  104.                                                 y=modsqrt;
  105.                                                 flag=1;
  106.                                                 break;
  107.                                         }
  108.                                                 flag=0;
  109.                                                 n++;
  110.                                 }
  111.                         }
  112.                         if(flag==1)
  113.                         {
  114.                                 eccPoint.p[j].x=i;
  115.                                 eccPoint.p[j].y=y;
  116.                                 j++;
  117.                                 if(y!=0)
  118.                                 {
  119.                                         eccPoint.p[j].x=i;
  120.                                         eccPoint.p[j].y=(N-y) % N;
  121.                                         j++;
  122.                                 }                               
  123.                         }
  124.                 }
  125.                 eccPoint.len=j;//点集个数
  126.                 print(); //打印点集
  127.         }       
  128. }

  129. //task3:求生成元以及阶
  130. void get_generetor_class()
  131. {       
  132.         int i,j=0;
  133.         int count=1;
  134.         Point p1,p2;
  135.         get_all_points();       
  136.         printf("\n**********************************输出生成元以及阶:*************************************\n");
  137.         for(i=0;i<eccPoint.len;i++)
  138.         {
  139.                 count=1;
  140.                 p1.x=p2.x=eccPoint.p[i].x;
  141.                 p1.y=p2.y=eccPoint.p[i].y;               
  142.                 while(1)
  143.                 {       
  144.                         p2=add_two_points(p1,p2);                                       
  145.                         if(p2.x==-1 && p2.y==-1)
  146.                         {
  147.                                 break;
  148.                         }
  149.                         count++;
  150.                         if(p2.x==p1.x)
  151.                         {
  152.                                 break;
  153.                         }                                               
  154.                 }
  155.                 count++;
  156.                 if(count<=eccPoint.len+1)
  157.                 {
  158.                         geneSet[j].p.x=p1.x;
  159.                         geneSet[j].p.y=p1.y;
  160.                         geneSet[j].p_class=count;
  161.                         printf("(%d,%d)--->>%d\t",geneSet[j].p.x,geneSet[j].p.y,geneSet[j].p_class);
  162.                         j++;
  163.                         if(j % 6 ==0){
  164.                                 printf("\n");
  165.                         }
  166.                 }
  167.                 geneLen=j;       
  168.         }
  169. }

  170. // 求 a mod b 的逆元
  171. void exGcd(int a, int b) {
  172.     if (b == 0) {
  173.         xy[0] = 1;
  174.         xy[1] = 0;
  175.     } else {
  176.         exGcd(b, a % b);
  177.         int x = xy[0];
  178.         xy[0] = xy[1];
  179.         xy[1] = x - (a / b) * xy[1];
  180.     }
  181.    
  182. }
  183. int calculate3(int y,int k,int p){

  184.         int l=1;
  185.         for(int i = 0;i<k;i++){
  186.                 l=l*y;
  187.                 l=l%p;
  188.         }

  189.         return l;
  190. }

  191. Point eccmutiply(int n,Point p){
  192.         int a,b,l,k,m;
  193.         a=p.x;
  194.         b=p.y;
  195.         for(int i = 0;i<n-1;i++){
  196.                
  197.                 if(a==p.x&&b==p.y){
  198.                         exGcd(2*p.y,N);
  199.                         k=xy[0];
  200.                         if(k<0)k=k+N;
  201.                         printf("逆元=%d\n",k);
  202.                         l=(3*p.x*p.x+A)*k;
  203.                         l=calculate3(l,1,N);
  204.                         if(l<0){
  205.                                 l=l+N;
  206.                         }
  207.                 }else{
  208.                         exGcd(a-p.x+N,N);
  209.                         k=xy[0];
  210.                         if(k<0)k=k+N;
  211.                         printf("else逆元=%d\n",k);
  212.                         l=(b-p.y)*k;
  213.                         l=calculate3(l,1,N);
  214.                         if(l<0){
  215.                                 l=l+N;
  216.                         }
  217.                         printf("l=%d\n",l);
  218.                 }
  219.                 m=p.x;
  220.                 a=l*l-a-p.x;
  221.                 a=calculate3(a,1,N);
  222.                 if(a<0){
  223.                         a=a+N;
  224.                 }
  225.                 b=l*(m-a)-p.y;
  226.                 b=calculate3(b,1,N);
  227.        
  228.                 if(b<0){
  229.                         b=b+N;
  230.                 }
  231.                 printf("%d(a,b)=(%d,%d)\n",i+2,a,b);
  232.                 //if(a==4&&b==5)break;
  233.         }
  234.         Point p3;
  235.         p3.x=a;
  236.         p3.y=b;
  237.         return p3;
  238. }
  239. Point mul(Point p1,Point p2){
  240.         int k,l;
  241.         exGcd(p2.x-p1.x+N,N);
  242.         k=xy[0];
  243.         if(k<0)k=k+N;
  244.         //printf("else逆元=%d\n",k);
  245.         l=(p2.y-p1.y)*k;
  246.         l=calculate3(l,1,N);
  247.         if(l<0){
  248.                 l=l+N;
  249.         }
  250.         //printf("l=%d\n",l);       
  251.         Point p3;
  252.         p3.x=l*l-p1.x-p2.x;
  253.         p3.x=calculate3(p3.x,1,N);
  254.         if(p3.x<0)p3.x=p3.x+N;
  255.        
  256.         p3.y=l*(p1.x-p3.x)-p1.y;
  257.         p3.y=calculate3(p3.y,1,N);
  258.         if(p3.y<0)p3.y=p3.y+N;
  259.         return p3;
  260. }

  261. //求b关于n的逆元
  262. int inverse(int n,int b)
  263. {
  264.         int q,r,r1=n,r2=b,t,t1=0,t2=1,i=1;
  265.         while(r2>0)
  266.         {
  267.                 q=r1/r2;
  268.                 r=r1%r2;
  269.                 r1=r2;
  270.                 r2=r;
  271.                 t=t1-q*t2;
  272.                 t1=t2;
  273.                 t2=t;
  274.         }
  275.         if(t1>=0)
  276.                 return t1%n;
  277.         else{  
  278.                 while((t1+i*n)<0)
  279.                         i++;
  280.                 return t1+i*n;
  281.         }
  282. }
  283. //两点的加法运算
  284. Point add_two_points(Point p1,Point p2)
  285. {
  286.         long t;
  287.         int x1=p1.x;
  288.         int y1=p1.y;
  289.         int x2=p2.x;
  290.         int y2=p2.y;
  291.         int tx,ty;
  292.         int x3,y3;
  293.         int flag=0;
  294.         //求
  295.         if((x2==x1)&& (y2==y1) )
  296.         {
  297.                 //相同点相加
  298.                 if(y1==0)
  299.                 {
  300.                         flag=1;
  301.                 }else{
  302.                         t=(3*x1*x1+a1)*inverse(N,2*y1) % N;
  303.                 }
  304.                 //printf("inverse(p,2*y1)=%d\n",inverse(p,2*y1));
  305.         }else{
  306.                 //不同点相加
  307.                 ty=y2-y1;
  308.                 tx=x2-x1;
  309.                 while(ty<0)
  310.                 {
  311.                         ty+=N;
  312.                 }
  313.                 while(tx<0)
  314.                 {
  315.                         tx+=N;
  316.                 }
  317.                 if(tx==0 && ty !=0)
  318.                 {
  319.                         flag=1;
  320.                 }else{
  321.                         t=ty*inverse(N,tx) % N;
  322.                 }
  323.         }
  324.         if(flag==1)
  325.         {
  326.                 p2.x=-1;
  327.                 p2.y=-1;
  328.         }else{
  329.                 x3=(t*t-x1-x2) % N;
  330.                 y3=(t*(x1-x3)-y1) % N;
  331.         //使结果在有限域GF(P)上
  332.                 while(x3<0)
  333.                 {
  334.                         x3+=N;
  335.                 }
  336.                 while(y3<0)
  337.                 {
  338.                         y3+=N;
  339.                 }
  340.                 p2.x=x3;
  341.                 p2.y=y3;
  342.         }       
  343.         return p2;
  344. }
  345. //task2:倍点运算的递归算法
  346. Point timesPiont(int k,Point p0)
  347. {
  348.         if(k==1){
  349.                 return p0;
  350.         }                
  351.         else if(k==2){
  352.                 return add_two_points(p0,p0);
  353.         }else{
  354.                 return add_two_points(p0,timesPiont(k-1,p0));
  355.         }
  356. }
  357. main(){
  358.         get_generetor_class();
  359.         Point p1,p2,p,p4,p5,p6,p7,p8,p9,p10;
  360.         int na,k,h,r,s,u1,u2;
  361.         printf("\n选择生成元:");
  362.         scanf("%d%d",&p1.x,&p1.y);
  363.         int j=0;
  364.         while(j<N){

  365.                 if(geneSet[j].p.x==p1.x&&geneSet[j].p.y==p1.y){
  366.                         break;
  367.                 }
  368.                 printf("j=%d\n",j);
  369.                 ++j;
  370.         }
  371.         int M = geneSet[j].p_class;
  372.         printf("M=%d",M);
  373. //        p1.x=0;
  374. //        p1.y=2;
  375.         //p.x=20;
  376.         //p.y=1;
  377.         printf("\n请输入私钥:");
  378.         scanf("%d",&na);
  379.         p2=eccmutiply(na,p1);
  380.         printf("\n公钥为(%d,%d)",p2.x,p2.y);
  381.         //p2=mul(p,p1);
  382.        
  383.         //printf("(%d,%d)",p2.x,p2.y);
  384.        
  385.         //签名过程
  386.         printf("\n\n输入随机数k:");
  387.         scanf("%d",&k);
  388.         printf("输入hash:");
  389.         scanf("%d",&h);
  390.        
  391.        
  392.         p4=eccmutiply(k,p1);
  393.         r=calculate3(p4.x,1,N);
  394.         if(r<0)r=r+N;
  395.         s=inverse(M,k)*(h+na*r)%M;
  396.         if(s<0)s=s+N;
  397.         printf("签名为(%d,%d)\n",r,s);
  398.         printf("========================");
  399.         //验证过程
  400.         u1=h*inverse(M,s)%M;
  401.        
  402.         if(u1<0)u1=u1+M;
  403.         u2=r*inverse(M,s)%M;

  404.         if(u2<0)u2=u2+M;

  405.         printf("u1u2=%d,%d\n",u1,u2);
  406.        
  407.         p5=eccmutiply(u1,p1);
  408.         printf("sG=(%d,%d)\n",p5.x,p5.y);
  409.        
  410.         p6=eccmutiply(u2,p2);
  411.         printf("HP=(%d,%d)\n",p6.x,p6.y);

  412.         p7=add_two_points(p5,p6);
  413.         printf("sG+HP=(%d,%d)\n",p7.x,p7.y);
  414.         if(calculate3(p7.x,1,N)==r){
  415.                 printf("通过");
  416.         }else{
  417.                 printf("失败");
  418.         }
  419.          
  420. }
复制代码

4.运行结果


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

教学服务系统

GMT+8, 2025-4-30 12:40 , Processed in 0.016370 second(s), 19 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表