教学服务系统

 找回密码
 立即注册
搜索
查看: 524|回复: 3

信息计算2019级2班30号高鹏

[复制链接]

10

主题

16

帖子

80

积分

注册会员

Rank: 2

积分
80
发表于 2022-6-2 15:32:40 | 显示全部楼层 |阅读模式
  实现RSA签名和加密

一.实现RSA签名和加密的原理

RSA加密是⼀种⾮对称加密。可以在不直接传递密钥的情况下,完成解密。这能够确保信息的安全性,避免了直接传递密钥所造成的被破解的风险。是由⼀对密钥来进⾏加解密的过程,分别称为公钥和私钥。两者之间有数学相关,该加密算法的原理就是对⼀极⼤整数做因数分解的困难性来保证安全性。通常个⼈保存私钥,公钥是公开的。


二.、RSA加密解密
 1.获取密钥,这⾥是产⽣密钥,实际应⽤中可以从各种存储介质上读取密钥
   2.加密
   3.解密


三.签名与验证
我们使用公钥进行加密,然后使用私钥解密。理论上反过来也行(私钥加密,公钥解密),但这不安全且大多数库(包括java.security)也不支持。然而,这种方式在构建API时比较有用。使用私钥对消息进行签名,然后使用公钥进行验证签名。这种机制可以确保消息确实来着公钥创建者(私钥持有者),使得传输过程消息不会被篡改。





本帖子中包含更多资源

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

x
回复

使用道具 举报

10

主题

16

帖子

80

积分

注册会员

Rank: 2

积分
80
 楼主| 发表于 2022-6-2 15:35:00 | 显示全部楼层
源代码:
  1. package rsa;

  2. import java.io.ByteArrayInputStream;
  3. import java.io.ByteArrayOutputStream;
  4. import java.io.InputStream;
  5. import java.security.Key;
  6. import java.security.KeyFactory;
  7. import java.security.KeyPair;
  8. import java.security.KeyPairGenerator;
  9. import java.security.PrivateKey;
  10. import java.security.PublicKey;
  11. import java.security.interfaces.RSAPrivateKey;
  12. import java.security.interfaces.RSAPublicKey;
  13. import java.security.spec.PKCS8EncodedKeySpec;
  14. import java.security.spec.X509EncodedKeySpec;
  15. import java.util.Base64;
  16. import javax.crypto.Cipher;

  17. public class RSAUtil{
  18.         
  19.         public static final String  SIGN_ALGORITHMS = "SHA1WithRSA";
  20.         
  21.     /**加密算法RSA*/
  22.     public static final String KEY_ALGORITHM = "RSA";
  23.    
  24.         /**RSA最大加密明文大小*/
  25.     private static final int MAX_ENCRYPT_BLOCK = 117;
  26.    
  27.     /**RSA最大解密密文大小*/
  28.     private static final int MAX_DECRYPT_BLOCK = 128;
  29.         
  30.         /**
  31.         * RSA签名
  32.         * @param content 待签名数据
  33.         * @param privateKey 商户私钥
  34.         * @param input_charset 编码格式
  35.         */
  36.         public static String sign(String content, String privateKey, String input_charset){
  37.         try {
  38.                 PKCS8EncodedKeySpec priPKCS8         = new PKCS8EncodedKeySpec(Base64_.decode(privateKey) );
  39.                 KeyFactory keyf                                 = KeyFactory.getInstance(KEY_ALGORITHM);
  40.                 PrivateKey priKey                                 = keyf.generatePrivate(priPKCS8);
  41.             java.security.Signature signature = java.security.Signature.getInstance(SIGN_ALGORITHMS);
  42.             signature.initSign(priKey);
  43.             signature.update(content.getBytes(input_charset));
  44.             byte[] signed = signature.sign();
  45.             return Base64_.encode(signed);
  46.         }catch (Exception e) {
  47.                 e.printStackTrace();
  48.         }
  49.         return null;
  50.     }
  51.         
  52.         /**
  53.         * RSA验签名检查
  54.         * @param content 待签名数据
  55.         * @param sign 签名值
  56.         * @param ali_public_key 支付宝公钥
  57.         * @param input_charset 编码格式
  58.         */
  59.         public static boolean verify(String content, String sign, String ali_public_key, String input_charset){
  60.                 try {
  61.                         KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
  62.                 byte[] encodedKey = Base64_.decode(ali_public_key);
  63.                 PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));
  64.                         java.security.Signature signature = java.security.Signature.getInstance(SIGN_ALGORITHMS);
  65.                         signature.initVerify(pubKey);
  66.                         signature.update(content.getBytes(input_charset) );
  67.                         boolean bverify = signature.verify( Base64_.decode(sign) );
  68.                         return bverify;
  69.                 } catch (Exception e) {
  70.                         e.printStackTrace();
  71.                 }
  72.                 return false;
  73.         }
  74.         
  75.         /**
  76.         * 私钥解密
  77.         * @param content 密文
  78.         * @param private_key 商户私钥
  79.         * @param input_charset 编码格式
  80.         */
  81.         public static String decrypt(String content, String private_key, String input_charset) throws Exception {
  82.         PrivateKey prikey = getPrivateKey(private_key);
  83.         Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
  84.         cipher.init(Cipher.DECRYPT_MODE, prikey);
  85.         InputStream ins = new ByteArrayInputStream(Base64_.decode(content));
  86.         ByteArrayOutputStream writer = new ByteArrayOutputStream();
  87.         //rsa解密的字节大小最多是128,将需要解密的内容,按128位拆开解密
  88.         byte[] buf = new byte[128];
  89.         int bufl;
  90.         while ((bufl = ins.read(buf)) != -1) {
  91.             byte[] block = null;
  92.             if (buf.length == bufl) {
  93.                 block = buf;
  94.             } else {
  95.                 block = new byte[bufl];
  96.                 for (int i = 0; i < bufl; i++) {
  97.                     block[i] = buf[i];
  98.                 }
  99.             }
  100.             writer.write(cipher.doFinal(block));
  101.         }
  102.         return new String(writer.toByteArray(), input_charset);
  103.     }
  104.         
  105.         /**
  106.      * 公钥加密
  107.      * @param data 源数据
  108.      * @param publicKey 公钥(BASE64编码)
  109.      */
  110.     public static byte[] encryptByPublicKey(byte[] data, String publicKey) throws Exception {
  111.         byte[] keyBytes = Base64_.decode(publicKey);
  112.         X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
  113.         KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
  114.         Key publicK = keyFactory.generatePublic(x509KeySpec);
  115.         // 对数据加密
  116.         Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
  117.         cipher.init(Cipher.ENCRYPT_MODE, publicK);
  118.         int inputLen = data.length;
  119.         ByteArrayOutputStream out = new ByteArrayOutputStream();
  120.         int offSet = 0;
  121.         byte[] cache;
  122.         int i = 0;
  123.         // 对数据分段加密
  124.         while (inputLen - offSet > 0) {
  125.             if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
  126.                 cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
  127.             } else {
  128.                 cache = cipher.doFinal(data, offSet, inputLen - offSet);
  129.             }
  130.             out.write(cache, 0, cache.length);
  131.             i++;
  132.             offSet = i * MAX_ENCRYPT_BLOCK;
  133.         }
  134.         byte[] encryptedData = out.toByteArray();
  135.         out.close();
  136.         return encryptedData;
  137.     }
  138.    
  139.     public static String encryptByPublicKeyToStr(byte[] data, String publicKey) throws Exception {
  140.             byte[] bytes = encryptByPublicKey(data, publicKey);
  141.             String result = Base64_.encode(bytes);
  142.             return result;
  143.     }
  144.         
  145.         /**
  146.         * 得到私钥
  147.         * @param key 密钥字符串(经过base64编码)
  148.         * @throws Exception
  149.         */
  150.         public static PrivateKey getPrivateKey(String key) throws Exception {
  151.                 byte[] keyBytes;
  152.                 keyBytes = Base64_.decode(key);
  153.                 PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
  154.                 KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
  155.                 PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
  156.                 return privateKey;
  157.         }
  158.         
  159.         public static class Base64_ {
  160.                 private static final Base64.Decoder decoder = Base64.getDecoder();
  161.                 private static final Base64.Encoder encoder = Base64.getEncoder();
  162.                 public static byte[] decode(String key) {
  163.                         if (key == null) { return null;}
  164.                         byte[] decode = decoder.decode(key);
  165.                         return decode;
  166.                 }
  167.                 public static String encode(byte[] content) {
  168.                         if (content == null) {return null;}
  169.                         String encode = encoder.encodeToString(content);
  170.                         return encode;
  171.                 }
  172.         }
  173.         
  174.         /**
  175.          * 测试
  176.          */
  177.         public static void main(String args[]) throws Exception{
  178.         KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
  179.         keyPairGen.initialize(1024);
  180.         KeyPair keyPair = keyPairGen.generateKeyPair();
  181.         RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
  182.         RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
  183.         String pubKey = Base64_.encode(publicKey.getEncoded()); //公钥
  184.         String priKey = Base64_.encode(privateKey.getEncoded()); //私钥
  185. //        System.out.println(pubKey);
  186. //        System.out.println(priKey);
  187.         
  188. //......................................公钥加密,私钥解密!
  189.         
  190.         String sourceStr = "Wise men don't fall in love, but a few kings are rich all the way";
  191.         //公钥加密
  192.         byte[] ens = RSAUtil.encryptByPublicKey(sourceStr.getBytes(),pubKey);
  193.         String encodes = Base64_.encode(ens);
  194.         System.out.println("公钥加密后:"+encodes);
  195.         //私钥解密
  196.         String res2 = RSAUtil.decrypt(encodes, priKey, "UTF-8");
  197.         System.out.println("私钥解密后:"+res2+",翻译:智者不入爱河,寡王一路硕博");
  198.         
  199. //.......................................签名验证,私钥签名,公钥验证是否正确!
  200.         
  201.         String source = "id=shoig&name=shoer&age=23dnjlegj;reg"; //模拟请求参数,然后对此请求参数进行签名。
  202.         
  203.         String sign = RSAUtil.sign(source, priKey, "UTF-8");
  204.         
  205.         System.out.println("签名是:"+sign);
  206.         
  207.         // 公钥验证签名是否正确.
  208.         // 具体流程是,请求参数+sign发送给公钥方,然后公钥方过滤掉sign,用公钥验证其他参数是否通过。
  209.         
  210.         boolean result = RSAUtil.verify(source, sign, pubKey, "UTF-8");
  211.         
  212.         System.out.println("验签结果是:"+result);
  213.         
  214.         }
  215. }
复制代码
运行截图:

本帖子中包含更多资源

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

x
回复

使用道具 举报

10

主题

16

帖子

80

积分

注册会员

Rank: 2

积分
80
 楼主| 发表于 2022-6-2 15:42:21 | 显示全部楼层
                       ECC椭圆曲线上公钥密码
一.算法原理
ECC 是 Elliptic Curves Cryptography 的缩写,意为椭圆曲线密码编码学。和RSA算法一样,ECC算法也属于公开密钥算法。最初由 Koblitz 和 Miller 两人于1985年提出,其数学基础是利用椭圆曲线上的有理点构成Abel加法群上椭圆离散对数的计算困难性。

二、执行过程
1、生成公钥和私钥;
2、公钥加密;
3、私钥解密;
4、用私钥对信息生成数字签名;
回复

使用道具 举报

10

主题

16

帖子

80

积分

注册会员

Rank: 2

积分
80
 楼主| 发表于 2022-6-2 15:46:04 | 显示全部楼层
源代码:
  1. #include "stdafx.h"
  2. #include <string>
  3. #include <iostream>
  4. using namespace std;
  5. const int k = 9;
  6. const int a = 5;
  7. const int b = 37;
  8. const int p = 127;
  9. const int r =7;

  10. int getX_1(int x,int mod){
  11.         int Q,X1,X2,X3,Y1,Y2,Y3,T1,T2,T3;
  12.         X1 = 1;
  13.         X2 = 0;
  14.         X3 = mod;
  15.         Y1 = 0;
  16.         Y2 = 1;
  17.         Y3 = (x%mod + mod) %mod;//获得正整数
  18.         while(Y3 != 1){
  19.                 Q = X3 / Y3;
  20.                 T1 = X1 - Q * Y1;
  21.                 T2 = X2 - Q * Y2;
  22.                 T3 = X3 - Q * Y3;
  23.                 X1 = Y1;
  24.                 X2 = Y2;
  25.                 X3 = Y3;
  26.                 Y1 = T1;
  27.                 Y2 = T2;
  28.                 Y3 = T3;
  29.         }
  30.         return Y2;
  31. }//获得其乘法逆元

  32. struct point{
  33.         int x;
  34.         int y;
  35. };
  36. point A,B;//公钥
  37. typedef pair<point,point> twopoint;
  38. bool operator == (point pa,point pb){
  39.         return pa.x == pb.x && pa.y == pb.y;
  40. }
  41. point operator + (point pa , point pb){
  42.         int k;
  43.         
  44.         if(pa == pb)
  45.                 k = ((3 * pa.x * pa.x + a) * getX_1(2* pa.y ,p)) % p ;
  46.         else
  47.                 k = (pb.y - pa.y) * getX_1(pb.x - pa.x , p) %p;
  48.                 point c;
  49.                 c.x = (k*k - pa.x -pb.x) %p;
  50.                 c.y = (k * (pa.x - c.x) - pa.y)%p ;
  51.                 c.x = (c.x + p) %p;
  52.                 c.y = (c.y + p) %p;
  53.                
  54.                 return c;
  55. }
  56. point operator * (point &b,int n){
  57.                 point q = b;
  58.                 n = n -1;
  59.                 for(int i = 1 ; i < n;i++){
  60.                         q = q + b ;
  61.                 }
  62.                 return q;
  63. }
  64. twopoint ECodePoint(point m){
  65.         point c1,c2;
  66.         c1 = A * r ;
  67.         point Y = B * r ;
  68.         c2.x = Y.x * m.x % p ;
  69.         c2.y = Y.y * m.y % p ;
  70.         return twopoint(c1,c2);
  71. }
  72. point DCodePoint(twopoint t){
  73.         point Z = t.first * k;
  74.         point m;
  75.         m.x = t.second.x * getX_1(Z.x,p) % p ;
  76.         m.y = t.second.y * getX_1(Z.y,p) % p ;
  77.         return m;
  78. }
  79. string ECode(string input){
  80.         string output = "";
  81.         point M;
  82.         twopoint C;
  83.         for(int i =0; i < input.length();i++){
  84.                 M.x = i;
  85.                 M.y = input[i];
  86.                 C = ECodePoint(M);
  87.                 output += (char)C.first.x ;
  88.                 output += (char)C.first.y ;
  89.                 output += (char)C.second.x ;
  90.                 output += (char)C.second.y ;
  91.         }
  92.         return output;
  93. }
  94. string DCode(string input){
  95.         string output = "";
  96.         point M;
  97.         twopoint C;
  98.         if(input.length()%4 != 0)
  99.                 return "错误输入";
  100.         for(int i = 0;i < input.length();){
  101.                 C.first.x = input[i++];
  102.                 C.first.y = input[i++];
  103.                 C.second.x = input[i++];
  104.                 C.second.y = input[i++];
  105.                 M = DCodePoint(C);
  106.                 output += (char)M.y;
  107.         }
  108.         return output;
  109. }
  110. int main()
  111. {
  112.         A.x = 11;
  113.         A.y = 4;
  114.         B = A*k;
  115.         string s = "";
  116.         cout<<"使用在素域上的曲线 y^2 = x^3 + 5*x +37   ,使用Menezes-Vanstone的算法:"<<endl;
  117.         cout<<"在素域p=127上,私钥为k=9,公钥A(11,4),B(120,41),对明文字符串直接转换为int进行加密"<<endl;
  118.         cout<<"请输入要加密的内容:"<<endl;
  119.         cin>>s;
  120.         cout<<"密文如下:"<<"\r\n";
  121.         s = ECode(s);
  122.         cout<<s<<endl;
  123.         cout<<"对之前密文解密,得到明文如下(由于输入密文不正确绝对会使这个程序出错,所以只能解密绝对安全的密文):"<<"\r\n";
  124.         s = DCode(s);
  125.         cout<<s<<"\r\n"<<"完成"<<endl;
  126.         cin>>s;
  127.         return 0;
  128. }
复制代码


回复

使用道具 举报

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

本版积分规则

教学服务系统

GMT+8, 2025-4-30 01:25 , Processed in 0.016518 second(s), 19 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

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