教学服务系统

 找回密码
 立即注册
搜索
查看: 904|回复: 7

信息计算2019级1班12号雷楚涵

[复制链接]

9

主题

26

帖子

103

积分

注册会员

Rank: 2

积分
103
发表于 2022-6-2 14:27:09 | 显示全部楼层 |阅读模式
RSA签名和加密

一、Java实现RSA签名和加密
RSA属于非对称加密算法,有两个密钥。区别于共享密钥的对称加密算法,如DES和AES。公钥可以共享给任何人,私钥自己进行保管。公钥用于加密数据,使得该加密数据只能用私钥进行解密;私钥也可用于签名数据,签名和数据一起发送,然后使用公钥验证数据是否被篡改。
二、RSA实现密钥对
在实际做任何形式加密之前,需要有公钥和私钥两个密钥对。幸运的是,Java提供了非常简单的方法,首先获得RSA KeyPairGenerator实例,然后使用2048为长度进行初始化并传入SecureRandom实例。后者用作生成器的熵或随机数据源。第三行生成密钥对,所有内容都就是这样,非常简单。如果需要使用密钥对存储器,需要使用Java KeyStore工具,后面会详细解释。
三、加密和解密
这里使用base64编码,主要是典型的REST API中很常用,我们当然也可以不用base64编码而直接使用字节数组。确保明确地且一致地为字符串指定字节编码。否则字节错位将导致密文和无法解密或验证签名。首先获得RSA密码实例并设置为加密模式,然后使用公钥加密消息。然后一次性传入消息字符串的字节数组并获得加密后的字节数组,最后转码并返回。运维RSA是相当慢,比对称加密算法如AES要慢的多。
四、签名与验证
我们使用公钥进行加密,然后使用私钥解密。理论上反过来也行(私钥加密,公钥解密),但这不安全且大多数库(包括java.security)也不支持。然而,这种方式在构建API时比较有用。使用私钥对消息进行签名,然后使用公钥进行验证签名。这种机制可以确保消息确实来着公钥创建者(私钥持有者),使得传输过程消息不会被篡改。


回复

使用道具 举报

9

主题

26

帖子

103

积分

注册会员

Rank: 2

积分
103
 楼主| 发表于 2022-6-2 14:28:53 | 显示全部楼层
本帖最后由 19信计1班雷楚涵 于 2022-6-2 14:31 编辑

程序代码:Base64.java
  1. package com.ihep;

  2. public final class Base64 {

  3.     static private final int     BASELENGTH           = 128;
  4.     static private final int     LOOKUPLENGTH         = 64;
  5.     static private final int     TWENTYFOURBITGROUP   = 24;
  6.     static private final int     EIGHTBIT             = 8;
  7.     static private final int     SIXTEENBIT           = 16;
  8.     static private final int     FOURBYTE             = 4;
  9.     static private final int     SIGN                 = -128;
  10.     static private final char    PAD                  = '=';
  11.     static private final boolean fDebug               = false;
  12.     static final private byte[]  base64Alphabet       = new byte[BASELENGTH];
  13.     static final private char[]  lookUpBase64Alphabet = new char[LOOKUPLENGTH];

  14.     static {
  15.         for (int i = 0; i < BASELENGTH; ++i) {
  16.             base64Alphabet[i] = -1;
  17.         }
  18.         for (int i = 'Z'; i >= 'A'; i--) {
  19.             base64Alphabet[i] = (byte) (i - 'A');
  20.         }
  21.         for (int i = 'z'; i >= 'a'; i--) {
  22.             base64Alphabet[i] = (byte) (i - 'a' + 26);
  23.         }

  24.         for (int i = '9'; i >= '0'; i--) {
  25.             base64Alphabet[i] = (byte) (i - '0' + 52);
  26.         }

  27.         base64Alphabet['+'] = 62;
  28.         base64Alphabet['/'] = 63;

  29.         for (int i = 0; i <= 25; i++) {
  30.             lookUpBase64Alphabet[i] = (char) ('A' + i);
  31.         }

  32.         for (int i = 26, j = 0; i <= 51; i++, j++) {
  33.             lookUpBase64Alphabet[i] = (char) ('a' + j);
  34.         }

  35.         for (int i = 52, j = 0; i <= 61; i++, j++) {
  36.             lookUpBase64Alphabet[i] = (char) ('0' + j);
  37.         }
  38.         lookUpBase64Alphabet[62] = (char) '+';
  39.         lookUpBase64Alphabet[63] = (char) '/';

  40.     }

  41.     private static boolean isWhiteSpace(char octect) {
  42.         return (octect == 0x20 || octect == 0xd || octect == 0xa || octect == 0x9);
  43.     }

  44.     private static boolean isPad(char octect) {
  45.         return (octect == PAD);
  46.     }

  47.     private static boolean isData(char octect) {
  48.         return (octect < BASELENGTH && base64Alphabet[octect] != -1);
  49.     }

  50.     public static String encode(byte[] binaryData) {

  51.         if (binaryData == null) {
  52.             return null;
  53.         }

  54.         int lengthDataBits = binaryData.length * EIGHTBIT;
  55.         if (lengthDataBits == 0) {
  56.             return "";
  57.         }

  58.         int fewerThan24bits = lengthDataBits % TWENTYFOURBITGROUP;
  59.         int numberTriplets = lengthDataBits / TWENTYFOURBITGROUP;
  60.         int numberQuartet = fewerThan24bits != 0 ? numberTriplets + 1 : numberTriplets;
  61.         char encodedData[] = null;

  62.         encodedData = new char[numberQuartet * 4];

  63.         byte k = 0, l = 0, b1 = 0, b2 = 0, b3 = 0;

  64.         int encodedIndex = 0;
  65.         int dataIndex = 0;
  66.         if (fDebug) {
  67.             System.out.println("number of triplets = " + numberTriplets);
  68.         }

  69.         for (int i = 0; i < numberTriplets; i++) {
  70.             b1 = binaryData[dataIndex++];
  71.             b2 = binaryData[dataIndex++];
  72.             b3 = binaryData[dataIndex++];

  73.             if (fDebug) {
  74.                 System.out.println("b1= " + b1 + ", b2= " + b2 + ", b3= " + b3);
  75.             }

  76.             l = (byte) (b2 & 0x0f);
  77.             k = (byte) (b1 & 0x03);

  78.             byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0);
  79.             byte val2 = ((b2 & SIGN) == 0) ? (byte) (b2 >> 4) : (byte) ((b2) >> 4 ^ 0xf0);
  80.             byte val3 = ((b3 & SIGN) == 0) ? (byte) (b3 >> 6) : (byte) ((b3) >> 6 ^ 0xfc);

  81.             if (fDebug) {
  82.                 System.out.println("val2 = " + val2);
  83.                 System.out.println("k4   = " + (k << 4));
  84.                 System.out.println("vak  = " + (val2 | (k << 4)));
  85.             }

  86.             encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];
  87.             encodedData[encodedIndex++] = lookUpBase64Alphabet[val2 | (k << 4)];
  88.             encodedData[encodedIndex++] = lookUpBase64Alphabet[(l << 2) | val3];
  89.             encodedData[encodedIndex++] = lookUpBase64Alphabet[b3 & 0x3f];
  90.         }

  91.         // form integral number of 6-bit groups
  92.         if (fewerThan24bits == EIGHTBIT) {
  93.             b1 = binaryData[dataIndex];
  94.             k = (byte) (b1 & 0x03);
  95.             if (fDebug) {
  96.                 System.out.println("b1=" + b1);
  97.                 System.out.println("b1<<2 = " + (b1 >> 2));
  98.             }
  99.             byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0);
  100.             encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];
  101.             encodedData[encodedIndex++] = lookUpBase64Alphabet[k << 4];
  102.             encodedData[encodedIndex++] = PAD;
  103.             encodedData[encodedIndex++] = PAD;
  104.         } else if (fewerThan24bits == SIXTEENBIT) {
  105.             b1 = binaryData[dataIndex];
  106.             b2 = binaryData[dataIndex + 1];
  107.             l = (byte) (b2 & 0x0f);
  108.             k = (byte) (b1 & 0x03);

  109.             byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0);
  110.             byte val2 = ((b2 & SIGN) == 0) ? (byte) (b2 >> 4) : (byte) ((b2) >> 4 ^ 0xf0);

  111.             encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];
  112.             encodedData[encodedIndex++] = lookUpBase64Alphabet[val2 | (k << 4)];
  113.             encodedData[encodedIndex++] = lookUpBase64Alphabet[l << 2];
  114.             encodedData[encodedIndex++] = PAD;
  115.         }

  116.         return new String(encodedData);
  117.     }

  118.     public static byte[] decode(String encoded) {

  119.         if (encoded == null) {
  120.             return null;
  121.         }

  122.         char[] base64Data = encoded.toCharArray();
  123.         // remove white spaces
  124.         int len = removeWhiteSpace(base64Data);

  125.         if (len % FOURBYTE != 0) {
  126.             return null;//should be divisible by four
  127.         }

  128.         int numberQuadruple = (len / FOURBYTE);

  129.         if (numberQuadruple == 0) {
  130.             return new byte[0];
  131.         }

  132.         byte decodedData[] = null;
  133.         byte b1 = 0, b2 = 0, b3 = 0, b4 = 0;
  134.         char d1 = 0, d2 = 0, d3 = 0, d4 = 0;

  135.         int i = 0;
  136.         int encodedIndex = 0;
  137.         int dataIndex = 0;
  138.         decodedData = new byte[(numberQuadruple) * 3];

  139.         for (; i < numberQuadruple - 1; i++) {

  140.             if (!isData((d1 = base64Data[dataIndex++])) || !isData((d2 = base64Data[dataIndex++]))
  141.                     || !isData((d3 = base64Data[dataIndex++]))
  142.                     || !isData((d4 = base64Data[dataIndex++]))) {
  143.                 return null;
  144.             }//if found "no data" just return null

  145.             b1 = base64Alphabet[d1];
  146.             b2 = base64Alphabet[d2];
  147.             b3 = base64Alphabet[d3];
  148.             b4 = base64Alphabet[d4];

  149.             decodedData[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);
  150.             decodedData[encodedIndex++] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
  151.             decodedData[encodedIndex++] = (byte) (b3 << 6 | b4);
  152.         }

  153.         if (!isData((d1 = base64Data[dataIndex++])) || !isData((d2 = base64Data[dataIndex++]))) {
  154.             return null;//if found "no data" just return null
  155.         }

  156.         b1 = base64Alphabet[d1];
  157.         b2 = base64Alphabet[d2];

  158.         d3 = base64Data[dataIndex++];
  159.         d4 = base64Data[dataIndex++];
  160.         if (!isData((d3)) || !isData((d4))) {//Check if they are PAD characters
  161.             if (isPad(d3) && isPad(d4)) {
  162.                 if ((b2 & 0xf) != 0)//last 4 bits should be zero
  163.                 {
  164.                     return null;
  165.                 }
  166.                 byte[] tmp = new byte[i * 3 + 1];
  167.                 System.arraycopy(decodedData, 0, tmp, 0, i * 3);
  168.                 tmp[encodedIndex] = (byte) (b1 << 2 | b2 >> 4);
  169.                 return tmp;
  170.             } else if (!isPad(d3) && isPad(d4)) {
  171.                 b3 = base64Alphabet[d3];
  172.                 if ((b3 & 0x3) != 0)//last 2 bits should be zero
  173.                 {
  174.                     return null;
  175.                 }
  176.                 byte[] tmp = new byte[i * 3 + 2];
  177.                 System.arraycopy(decodedData, 0, tmp, 0, i * 3);
  178.                 tmp[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);
  179.                 tmp[encodedIndex] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
  180.                 return tmp;
  181.             } else {
  182.                 return null;
  183.             }
  184.         } else { //No PAD e.g 3cQl
  185.             b3 = base64Alphabet[d3];
  186.             b4 = base64Alphabet[d4];
  187.             decodedData[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);
  188.             decodedData[encodedIndex++] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
  189.             decodedData[encodedIndex++] = (byte) (b3 << 6 | b4);

  190.         }

  191.         return decodedData;
  192.     }

  193.     private static int removeWhiteSpace(char[] data) {
  194.         if (data == null) {
  195.             return 0;
  196.         }

  197.         // count characters that's not whitespace
  198.         int newSize = 0;
  199.         int len = data.length;
  200.         for (int i = 0; i < len; i++) {
  201.             if (!isWhiteSpace(data[i])) {
  202.                 data[newSize++] = data[i];
  203.             }
  204.         }
  205.         return newSize;
  206.     }
  207. }
复制代码


回复

使用道具 举报

9

主题

26

帖子

103

积分

注册会员

Rank: 2

积分
103
 楼主| 发表于 2022-6-2 14:35:19 | 显示全部楼层

maintest.java
  1. package com.ihep;

  2. public class MainTest {

  3.     public static void main(String[] args) throws Exception {
  4.         String filepath = "E:/tmp/";

  5.         // 生成公钥和私钥文件
  6.         RSAEncrypt.genKeyPair(filepath);

  7.         System.out.println("--------------公钥加密私钥解密过程-------------------");
  8.         String plainText = "湖人总冠军";
  9.         // 公钥加密过程,得到加密后的数据
  10.         byte[] cipherData = RSAEncrypt.encrypt(RSAEncrypt.loadPublicKeyByStr(RSAEncrypt.loadPublicKeyByFile(filepath)), plainText.getBytes());
  11.         // 对加密数据进行编码处理,得到加密后的字符串
  12.         String cipher = Base64.encode(cipherData);
  13.         // 私钥解密过程
  14.         byte[] res = RSAEncrypt.decrypt(RSAEncrypt.loadPrivateKeyByStr(RSAEncrypt.loadPrivateKeyByFile(filepath)), Base64.decode(cipher));
  15.         String restr = new String(res);
  16.         System.out.println("原文:" + plainText);
  17.         System.out.println("加密:" + cipher);
  18.         System.out.println("解密:" + restr);
  19.         System.out.println();

  20.         System.out.println("--------------私钥加密公钥解密过程-------------------");
  21.         plainText = "湖人总冠军";
  22.         //私钥加密过程
  23.         cipherData = RSAEncrypt.encrypt(RSAEncrypt.loadPrivateKeyByStr(RSAEncrypt.loadPrivateKeyByFile(filepath)), plainText.getBytes());
  24.         cipher = Base64.encode(cipherData);
  25.         //公钥解密过程
  26.         res = RSAEncrypt.decrypt(RSAEncrypt.loadPublicKeyByStr(RSAEncrypt.loadPublicKeyByFile(filepath)), Base64.decode(cipher));
  27.         restr = new String(res);
  28.         System.out.println("原文:" + plainText);
  29.         System.out.println("加密:" + cipher);
  30.         System.out.println("解密:" + restr);
  31.         System.out.println();

  32.         System.out.println("---------------私钥签名过程------------------");
  33.         String content = "勒布朗·詹姆斯";
  34.         String signstr = RSASignature.sign(content, RSAEncrypt.loadPrivateKeyByFile(filepath));
  35.         System.out.println("签名原串:" + content);
  36.         System.out.println("签名串:" + signstr);
  37.         System.out.println();

  38.         System.out.println("---------------公钥校验签名------------------");
  39.         System.out.println("签名原串:" + content);
  40.         System.out.println("签名串:" + signstr);

  41.         System.out.println("验签结果:" + RSASignature.doCheck(content, signstr, RSAEncrypt.loadPublicKeyByFile(filepath)));
  42.         System.out.println();

  43.     }
  44. }
复制代码


回复

使用道具 举报

9

主题

26

帖子

103

积分

注册会员

Rank: 2

积分
103
 楼主| 发表于 2022-6-2 14:36:48 | 显示全部楼层

RSAEncrypt.java
  1. package com.ihep;

  2. import javax.crypto.BadPaddingException;
  3. import javax.crypto.Cipher;
  4. import javax.crypto.IllegalBlockSizeException;
  5. import javax.crypto.NoSuchPaddingException;
  6. import java.io.*;
  7. import java.security.*;
  8. import java.security.interfaces.RSAPrivateKey;
  9. import java.security.interfaces.RSAPublicKey;
  10. import java.security.spec.InvalidKeySpecException;
  11. import java.security.spec.PKCS8EncodedKeySpec;
  12. import java.security.spec.X509EncodedKeySpec;
  13. private static final char[] HEX_CHAR = {'0', '1', '2', '3', '4', '5', '6',
  14. '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
  15. public static void genKeyPair(String filePath) {
  16. // 密钥对生成器
  17. KeyPairGenerator keyPairGen = null;
  18. try {
  19. // KeyPairGenerator类用于生成公钥和私钥对,基于RSA算法生成对象
  20. keyPairGen = KeyPairGenerator.getInstance("RSA");
  21. } catch (NoSuchAlgorithmException e) {
  22. // TODO Auto-generated catch block
  23. e.printStackTrace();
  24. }
  25. // 初始化密钥对生成器,密钥大小为96-1024位
  26. keyPairGen.initialize(1024, new SecureRandom());
  27. // 生成一个密钥对,保存在keyPair中
  28. KeyPair keyPair = keyPairGen.generateKeyPair();
  29. // 得到私钥
  30. RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
  31. // 得到公钥
  32. RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
  33. try {
  34. // 得到公钥字符串
  35. String publicKeyString = Base64.encode(publicKey.getEncoded());
  36. // 得到私钥字符串
  37. String privateKeyString = Base64.encode(privateKey.getEncoded());
  38. // 将密钥对写入到文件
  39. FileWriter pubfw = new FileWriter(filePath + "/publicKey.keystore");
  40. FileWriter prifw = new FileWriter(filePath + "/privateKey.keystore");
  41. BufferedWriter pubbw = new BufferedWriter(pubfw);
  42. BufferedWriter pribw = new BufferedWriter(prifw);
  43. pubbw.write(publicKeyString);
  44. pribw.write(privateKeyString);
  45. pubbw.flush();
  46. pubbw.close();
  47. pubfw.close();
  48. pribw.flush();
  49. pribw.close();
  50. prifw.close();
  51. } catch (Exception e) {
  52. e.printStackTrace();
  53. }
  54. }
  55. public static String loadPublicKeyByFile(String path) throws Exception {
  56. try {
  57. BufferedReader br = new BufferedReader(new FileReader(path
  58. + "/publicKey.keystore"));
  59. String readLine = null;
  60. StringBuilder sb = new StringBuilder();
  61. while ((readLine = br.readLine()) != null) {
  62. sb.append(readLine);
  63. }
  64. br.close();
  65. return sb.toString();
  66. } catch (IOException e) {
  67. throw new Exception("公钥数据流读取错误");
  68. } catch (NullPointerException e) {
  69. throw new Exception("公钥输入流为空");
  70. }
  71. }
  72. public static RSAPublicKey loadPublicKeyByStr(String publicKeyStr)
  73. throws Exception {
  74. try {
  75. byte[] buffer = Base64.decode(publicKeyStr);
  76. KeyFactory keyFactory = KeyFactory.getInstance("RSA");
  77. X509EncodedKeySpec keySpec = new X509EncodedKeySpec(buffer);
  78. return (RSAPublicKey) keyFactory.generatePublic(keySpec);
  79. } catch (NoSuchAlgorithmException e) {
  80. throw new Exception("无此算法");
  81. } catch (InvalidKeySpecException e) {
  82. throw new Exception("公钥非法");
  83. } catch (NullPointerException e) {
  84. throw new Exception("公钥数据为空");
  85. }
  86. }
  87. public static String loadPrivateKeyByFile(String path) throws Exception {
  88. try {
  89. BufferedReader br = new BufferedReader(new FileReader(path
  90. + "/privateKey.keystore"));
  91. String readLine = null;
  92. StringBuilder sb = new StringBuilder();
  93. while ((readLine = br.readLine()) != null) {
  94. sb.append(readLine);
  95. }
  96. br.close();
  97. /** 该字符串从私钥文件中获取,称之为私钥字符串
  98. * MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBALaIDyyav7J8oD/8sONfP772aa1foDlHmoXRArqe+2po14c1q7nGR8DLk
  99. * 55J0sgxt/EOvtvxtwo4cPFtoLSBzdKVn/ZmR7uyHQXsMzqcmz7n7DGAzNNqxlu0SLHVjZ4HscWxnC+dGa037Ec9m5DKRT6aMckNmxZp3G
  100. * xic9wzId6zAgMBAAECgYEAhpOUFH/XvEH0aJjm1gzA1AubaI8rc2/edrDeQTe8B/1agr7IaMTO3E97++VT+fPmOV10zHbPTELGysnYBZ3
  101. * 6X/wLaKs+GMO/uewNAsyu46u3izwNVCygBiM62mlmhk3Y9J8ZcmoQHzXGV0p0TuGJsIlAofCAN1ielWLPcEVUPckCQQDoQm4GKe2C26oU
  102. * aXRwLy2WLczfmqLTlJ8QyJs8ruL78JikhDgLWaLPBJ+lHmTxahC4HjJ9LhNxNVcpbyMiHhM1AkEAyTBjkOGwBJTlYMmS1hn6BoqA5xCRF
  103. * Iv8gZZMxj+xcvSSEfZU9ObVArOBQRUoIO3GdsyaVfG/DNwuP7zGI16/RwJBAMfyIEu4HpsvxeyKmE3Xn5QQ27WHpzMkWAeX22RTXl7r0k
  104. * yW8rR6txkm7tS0JMxbtgb7IBX564zjEaU+4u0FHR0CQG+v+zYM9Ag3GHd4r5lH5nMHJLQhkEjVxaGy7IAKD9p/Ry/NjjA+jPXo7NJSimp
  105. * tVYXR48PeZm8fNFWR2HT+PjUCQFu3yN71iiXA0EW35Y1HHIE814gUV/O5T4gpUNzK9NLvHLFQNbzgoZER5yIGgBWDju1keBkojm8P69A7
  106. * qdtXILU=
  107. */
  108. return sb.toString();
  109. } catch (IOException e) {
  110. throw new Exception("私钥数据读取错误");
  111. } catch (NullPointerException e) {
  112. throw new Exception("私钥输入流为空");
  113. }
  114. }
  115. public static RSAPrivateKey loadPrivateKeyByStr(String privateKeyStr)
  116. throws Exception {
  117. try {
  118. byte[] buffer = Base64.decode(privateKeyStr);
  119. PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(buffer);
  120. KeyFactory keyFactory = KeyFactory.getInstance("RSA");
  121. return (RSAPrivateKey) keyFactory.generatePrivate(keySpec);
  122. } catch (NoSuchAlgorithmException e) {
  123. throw new Exception("无此算法");
  124. } catch (InvalidKeySpecException e) {
  125. throw new Exception("私钥非法");
  126. } catch (NullPointerException e) {
  127. throw new Exception("私钥数据为空");
  128. }
  129. }
  130. public static byte[] encrypt(RSAPublicKey publicKey, byte[] plainTextData)
  131. throws Exception {
  132. if (publicKey == null) {
  133. throw new Exception("加密公钥为空, 请设置");
  134. }
  135. Cipher cipher = null;
  136. try {
  137. // 使用默认RSA
  138. cipher = Cipher.getInstance("RSA");
  139. // cipher= Cipher.getInstance("RSA", new BouncyCastleProvider());
  140. // 初始化算法:公钥加密
  141. cipher.init(Cipher.ENCRYPT_MODE, publicKey);
  142. // 公钥加密后的字节数组
  143. byte[] output = cipher.doFinal(plainTextData);
  144. return output;
  145. } catch (NoSuchAlgorithmException e) {
  146. throw new Exception("无此加密算法");
  147. } catch (NoSuchPaddingException e) {
  148. e.printStackTrace();
  149. return null;
  150. } catch (InvalidKeyException e) {
  151. throw new Exception("加密公钥非法,请检查");
  152. } catch (IllegalBlockSizeException e) {
  153. throw new Exception("明文长度非法");
  154. } catch (BadPaddingException e) {
  155. throw new Exception("明文数据已损坏");
  156. }
  157. }

  158. public static byte[] encrypt(RSAPrivateKey privateKey, byte[] plainTextData)
  159. throws Exception {
  160. if (privateKey == null) {
  161. throw new Exception("加密私钥为空, 请设置");
  162. }
  163. Cipher cipher = null;
  164. try {
  165. // 使用默认RSA
  166. cipher = Cipher.getInstance("RSA");
  167. // 初始化算法:私钥加密
  168. cipher.init(Cipher.ENCRYPT_MODE, privateKey);
  169. // 加密后的密文数据,以字符数组的形式存在
  170. byte[] output = cipher.doFinal(plainTextData);
  171. return output;
  172. } catch (NoSuchAlgorithmException e) {
  173. throw new Exception("无此加密算法");
  174. } catch (NoSuchPaddingException e) {
  175. e.printStackTrace();
  176. return null;
  177. } catch (InvalidKeyException e) {
  178. throw new Exception("加密私钥非法,请检查");
  179. } catch (IllegalBlockSizeException e) {
  180. throw new Exception("明文长度非法");
  181. } catch (BadPaddingException e) {
  182. throw new Exception("明文数据已损坏");
  183. }
  184. }

  185. public static byte[] decrypt(RSAPrivateKey privateKey, byte[] cipherData)
  186. throws Exception {
  187. if (privateKey == null) {
  188. throw new Exception("解密私钥为空, 请设置");
  189. }
  190. Cipher cipher = null;
  191. try {
  192. // 使用默认RSA
  193. cipher = Cipher.getInstance("RSA");
  194. // cipher= Cipher.getInstance("RSA", new BouncyCastleProvider());
  195. // 初始化解密算法:私钥解密
  196. cipher.init(Cipher.DECRYPT_MODE, privateKey);
  197. // 解密,生成以字符数组形式存在的明文数据
  198. byte[] output = cipher.doFinal(cipherData);
  199. return output;
  200. } catch (NoSuchAlgorithmException e) {
  201. throw new Exception("无此解密算法");
  202. } catch (NoSuchPaddingException e) {
  203. e.printStackTrace();
  204. return null;
  205. } catch (InvalidKeyException e) {
  206. throw new Exception("解密私钥非法,请检查");
  207. } catch (IllegalBlockSizeException e) {
  208. throw new Exception("密文长度非法");
  209. } catch (BadPaddingException e) {
  210. throw new Exception("密文数据已损坏");
  211. }
  212. }
  213. public static byte[] decrypt(RSAPublicKey publicKey, byte[] cipherData)
  214. throws Exception {
  215. if (publicKey == null) {
  216. throw new Exception("解密公钥为空, 请设置");
  217. }
  218. Cipher cipher = null;
  219. try {
  220. // 使用默认RSA
  221. cipher = Cipher.getInstance("RSA");
  222. // cipher= Cipher.getInstance("RSA", new BouncyCastleProvider());
  223. // 初始化加密算法:公钥解密
  224. cipher.init(Cipher.DECRYPT_MODE, publicKey);
  225. byte[] output = cipher.doFinal(cipherData);
  226. // 以字符数组形式存在的明文数据
  227. return output;
  228. } catch (NoSuchAlgorithmException e) {
  229. throw new Exception("无此解密算法");
  230. } catch (NoSuchPaddingException e) {
  231. e.printStackTrace();
  232. return null;
  233. } catch (InvalidKeyException e) {
  234. throw new Exception("解密公钥非法,请检查");
  235. } catch (IllegalBlockSizeException e) {
  236. throw new Exception("密文长度非法");
  237. } catch (BadPaddingException e) {
  238. throw new Exception("密文数据已损坏");
  239. }
  240. }
  241. public static String byteArrayToString(byte[] data) {
  242. StringBuilder stringBuilder = new StringBuilder();
  243. for (int i = 0; i < data.length; i++) {
  244. // 取出字节的高四位 作为索引得到相应的十六进制标识符 注意无符号右移
  245. stringBuilder.append(HEX_CHAR[(data[i] & 0xf0) >>> 4]);
  246. // 取出字节的低四位 作为索引得到相应的十六进制标识符
  247. stringBuilder.append(HEX_CHAR[(data[i] & 0x0f)]);
  248. if (i < data.length - 1) {
  249. stringBuilder.append(' ');
  250. }
  251. }
  252. return stringBuilder.toString();
  253. }
  254. }
复制代码
回复

使用道具 举报

9

主题

26

帖子

103

积分

注册会员

Rank: 2

积分
103
 楼主| 发表于 2022-6-2 14:37:44 | 显示全部楼层


RSASignature.java
  1. package com.ihep;

  2. import java.security.KeyFactory;
  3. import java.security.PrivateKey;
  4. import java.security.PublicKey;
  5. import java.security.spec.PKCS8EncodedKeySpec;
  6. import java.security.spec.X509EncodedKeySpec;

  7. /**
  8. * RSA签名验签类
  9. */
  10. public class RSASignature {

  11.     /**
  12.      * 签名算法
  13.      */
  14.     public static final String SIGN_ALGORITHMS = "SHA1WithRSA";

  15.     public static String sign(String content, String privateKey, String encode) {
  16.         try {
  17.             PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(Base64.decode(privateKey));

  18.             KeyFactory keyf = KeyFactory.getInstance("RSA");
  19.             PrivateKey priKey = keyf.generatePrivate(priPKCS8);

  20.             java.security.Signature signature = java.security.Signature.getInstance(SIGN_ALGORITHMS);

  21.             signature.initSign(priKey);
  22.             signature.update(content.getBytes(encode));

  23.             byte[] signed = signature.sign();

  24.             return Base64.encode(signed);
  25.         } catch (Exception e) {
  26.             e.printStackTrace();
  27.         }

  28.         return null;
  29.     }

  30.     public static String sign(String content, String privateKey) {
  31.         try {
  32.             PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(Base64.decode(privateKey));
  33.             KeyFactory keyf = KeyFactory.getInstance("RSA");
  34.             PrivateKey priKey = keyf.generatePrivate(priPKCS8);
  35.             // 这里签名使用的是 SHA1WithRSA
  36.             java.security.Signature signature = java.security.Signature.getInstance(SIGN_ALGORITHMS);
  37.             // 以私钥字符串初始化签名
  38.             signature.initSign(priKey);
  39.             // 将原始串注入签名中
  40.             signature.update(content.getBytes());
  41.             // 签名后的结果,以字符数组形式存在
  42.             byte[] signed = signature.sign();
  43.             // 签名后的结果,以base64编码形式存在
  44.             return Base64.encode(signed);
  45.         } catch (Exception e) {
  46.             e.printStackTrace();
  47.         }
  48.         return null;
  49.     }

  50.     public static boolean doCheck(String content, String sign, String publicKey, String encode) {
  51.         try {
  52.             KeyFactory keyFactory = KeyFactory.getInstance("RSA");
  53.             byte[] encodedKey = Base64.decode(publicKey);
  54.             PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));


  55.             java.security.Signature signature = java.security.Signature
  56.                     .getInstance(SIGN_ALGORITHMS);

  57.             signature.initVerify(pubKey);
  58.             signature.update(content.getBytes(encode));

  59.             boolean bverify = signature.verify(Base64.decode(sign));
  60.             return bverify;

  61.         } catch (Exception e) {
  62.             e.printStackTrace();
  63.         }

  64.         return false;
  65.     }

  66.     public static boolean doCheck(String content, String sign, String publicKey) {
  67.         try {
  68.             KeyFactory keyFactory = KeyFactory.getInstance("RSA");
  69.             byte[] encodedKey = Base64.decode(publicKey);
  70.             PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));
  71.             // 使用 SHA1WithRSA 签名算法
  72.             java.security.Signature signature = java.security.Signature
  73.                     .getInstance(SIGN_ALGORITHMS);
  74.             // 用公钥初始化签名校验
  75.             signature.initVerify(pubKey);
  76.             // 原始串注入签名校验中
  77.             signature.update(content.getBytes());
  78.             // 验证签名结果
  79.             boolean bverify = signature.verify(Base64.decode(sign));
  80.             // 返回签名是否成功
  81.             return bverify;
  82.         } catch (Exception e) {
  83.             e.printStackTrace();
  84.         }
  85.         return false;
  86.     }
  87. }
复制代码
回复

使用道具 举报

9

主题

26

帖子

103

积分

注册会员

Rank: 2

积分
103
 楼主| 发表于 2022-6-2 14:56:54 | 显示全部楼层
本帖最后由 19信计1班雷楚涵 于 2022-6-2 14:58 编辑

                                                            ECC-椭圆曲线加密算法
一、算法简介
椭圆加密算法(ECC)是一种公钥加密体制,最初由Koblitz和Miller两人于1985年提出,其数学基础是利用椭圆曲线上的有理点构成Abel加法群上椭圆离散对数的计算困难性。公钥密码体制根据其所依据的难题一般分为三类:大素数分解问题类、离散对数问题类、椭圆曲线类。有时也把椭圆曲线类归为离散对数类。
ECC的主要优势是在某些情况下它比其他的方法使用更小的密钥——比如RSA加密算法——提供相当的或更高等级的安全。ECC的另一个优势是可以定义群之间的双线性映射,基于Weil对或是Tate对;双线性映射已经在密码学中发现了大量的应用,例如基于身份的加密。不过一个缺点是加密和解密操作的实现比其他机制花费的时间长。

二、基本原理
设私钥、公钥分别为d、Q,即Q = dG,其中G为基点,椭圆曲线上的已知G和dG,求d是非常困难的,也就是说已知公钥和基点,想要算出私钥是非常困难的。
公钥加密:选择随机数r,将消息M生成密文C,该密文是一个点对,C = {rG, M+rQ},其中Q为公钥。
私钥解密:M + rQ - d(rG) = M + r(dG) - d(rG) = M,其中d、Q分别为私钥、公钥。

椭圆曲线签名算法(ECDSA)

设私钥、公钥分别为d、Q,即Q = dG,其中G为基点。
私钥签名
选择随机数r,计算点rG(x, y)。
根据随机数r、消息M的哈希h、私钥d,计算s = (h + dx)/r。  
将消息M、和签名{rG, s}发给接收方。

公钥验证签名:
接收方收到消息M、以及签名{rG=(x,y), s}。  
根据消息求哈希h。  
使用发送方公钥Q计算:hG/s + xQ/s,并与rG比较,如相等即验签成功。
原理:hG/s + xQ/s = hG/s + xG)/s = (h+xd)G/s = r(h+xd)G / (h+dx) = rG



回复

使用道具 举报

9

主题

26

帖子

103

积分

注册会员

Rank: 2

积分
103
 楼主| 发表于 2022-6-2 15:03:53 | 显示全部楼层
19信计1班雷楚涵 发表于 2022-6-2 14:56
ECC-椭圆曲线加密算法
一、算法简介
椭圆 ...

三、代码
  1. # include <stdio.h>
  2. # include <math.h>
  3. using System.Drawing;

  4. int xy[22];

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

  140. //task3:求生成元以及阶
  141. void get_generetor_class()
  142. {
  143.         int i, j = 0;
  144.         int count = 1;
  145.         Point p1, p2;
  146.         get_all_points();
  147.         printf("\n**********************************输出生成元以及阶:*************************************\n");
  148.         for (i = 0; i < eccPoint.len; i++)
  149.         {
  150.                 count = 1;
  151.                 p1.x = p2.x = eccPoint.p[i].x;
  152.                 p1.y = p2.y = eccPoint.p[i].y;
  153.                 while (1)
  154.                 {
  155.                         p2 = add_two_points(p1, p2);
  156.                         if (p2.x == -1 && p2.y == -1)
  157.                         {
  158.                                 break;
  159.                         }
  160.                         count++;
  161.                         if (p2.x == p1.x)
  162.                         {
  163.                                 break;
  164.                         }
  165.                 }
  166.                 count++;
  167.                 if (count <= eccPoint.len + 1)
  168.                 {
  169.                         geneSet[j].p.x = p1.x;
  170.                         geneSet[j].p.y = p1.y;
  171.                         geneSet[j].p_class = count;
  172.                         printf("(%d,%d)--->>%d\t", geneSet[j].p.x, geneSet[j].p.y, geneSet[j].p_class);
  173.                         j++;
  174.                         if (j % 6 == 0)
  175.                         {
  176.                                 printf("\n");
  177.                         }
  178.                 }
  179.                 geneLen = j;
  180.         }
  181. }
复制代码


回复

使用道具 举报

9

主题

26

帖子

103

积分

注册会员

Rank: 2

积分
103
 楼主| 发表于 2022-6-2 15:05:03 | 显示全部楼层
  1. // 求 a mod b 的逆元
  2. void exGcd(int a, int b)
  3. {
  4.         if (b == 0)
  5.         {
  6.                 xy[0] = 1;
  7.                 xy[1] = 0;
  8.         }
  9.         else
  10.         {
  11.                 exGcd(b, a % b);
  12.                 int x = xy[0];
  13.                 xy[0] = xy[1];
  14.                 xy[1] = x - (a / b) * xy[1];
  15.         }

  16. }
  17. int calculate3(int y, int k, int p)
  18. {

  19.         int l = 1;
  20.         for (int i = 0; i < k; i++)
  21.         {
  22.                 l = l * y;
  23.                 l = l % p;
  24.         }

  25.         return l;
  26. }

  27. Point eccmutiply(int n, Point p)
  28. {
  29.         int a, b, l, k, m;
  30.         a = p.x;
  31.         b = p.y;
  32.         for (int i = 0; i < n - 1; i++)
  33.         {

  34.                 if (a == p.x && b == p.y)
  35.                 {
  36.                         exGcd(2 * p.y, N);
  37.                         k = xy[0];
  38.                         if (k < 0) k = k + N;
  39.                         printf("逆元=%d\n", k);
  40.                         l = (3 * p.x * p.x + A) * k;
  41.                         l = calculate3(l, 1, N);
  42.                         if (l < 0)
  43.                         {
  44.                                 l = l + N;
  45.                         }
  46.                 }
  47.                 else
  48.                 {
  49.                         exGcd(a - p.x + N, N);
  50.                         k = xy[0];
  51.                         if (k < 0) k = k + N;
  52.                         printf("else逆元=%d\n", k);
  53.                         l = (b - p.y) * k;
  54.                         l = calculate3(l, 1, N);
  55.                         if (l < 0)
  56.                         {
  57.                                 l = l + N;
  58.                         }
  59.                         printf("l=%d\n", l);
  60.                 }
  61.                 m = p.x;
  62.                 a = l * l - a - p.x;
  63.                 a = calculate3(a, 1, N);
  64.                 if (a < 0)
  65.                 {
  66.                         a = a + N;
  67.                 }
  68.                 b = l * (m - a) - p.y;
  69.                 b = calculate3(b, 1, N);

  70.                 if (b < 0)
  71.                 {
  72.                         b = b + N;
  73.                 }
  74.                 printf("%d(a,b)=(%d,%d)\n", i + 2, a, b);
  75.                 //if(a==4&&b==5)break;
  76.         }
  77.         Point p3;
  78.         p3.x = a;
  79.         p3.y = b;
  80.         return p3;
  81. }
  82. Point mul(Point p1, Point p2)
  83. {
  84.         int k, l;
  85.         exGcd(p2.x - p1.x + N, N);
  86.         k = xy[0];
  87.         if (k < 0) k = k + N;
  88.         //printf("else逆元=%d\n",k);
  89.         l = (p2.y - p1.y) * k;
  90.         l = calculate3(l, 1, N);
  91.         if (l < 0)
  92.         {
  93.                 l = l + N;
  94.         }
  95.         //printf("l=%d\n",l);      
  96.         Point p3;
  97.         p3.x = l * l - p1.x - p2.x;
  98.         p3.x = calculate3(p3.x, 1, N);
  99.         if (p3.x < 0) p3.x = p3.x + N;

  100.         p3.y = l * (p1.x - p3.x) - p1.y;
  101.         p3.y = calculate3(p3.y, 1, N);
  102.         if (p3.y < 0) p3.y = p3.y + N;
  103.         return p3;
  104. }

  105. //求b关于n的逆元
  106. int inverse(int n, int b)
  107. {
  108.         int q, r, r1 = n, r2 = b, t, t1 = 0, t2 = 1, i = 1;
  109.         while (r2 > 0)
  110.         {
  111.                 q = r1 / r2;
  112.                 r = r1 % r2;
  113.                 r1 = r2;
  114.                 r2 = r;
  115.                 t = t1 - q * t2;
  116.                 t1 = t2;
  117.                 t2 = t;
  118.         }
  119.         if (t1 >= 0)
  120.                 return t1 % n;
  121.         else
  122.         {
  123.                 while ((t1 + i * n) < 0)
  124.                         i++;
  125.                 return t1 + i * n;
  126.         }
  127. }
  128. //两点的加法运算
  129. Point add_two_points(Point p1, Point p2)
  130. {
  131.         long t;
  132.         int x1 = p1.x;
  133.         int y1 = p1.y;
  134.         int x2 = p2.x;
  135.         int y2 = p2.y;
  136.         int tx, ty;
  137.         int x3, y3;
  138.         int flag = 0;
  139.         //求
  140.         if ((x2 == x1) && (y2 == y1))
  141.         {
  142.                 //相同点相加
  143.                 if (y1 == 0)
  144.                 {
  145.                         flag = 1;
  146.                 }
  147.                 else
  148.                 {
  149.                         t = (3 * x1 * x1 + a1) * inverse(N, 2 * y1) % N;
  150.                 }
  151.                 //printf("inverse(p,2*y1)=%d\n",inverse(p,2*y1));
  152.         }
  153.         else
  154.         {
  155.                 //不同点相加
  156.                 ty = y2 - y1;
  157.                 tx = x2 - x1;
  158.                 while (ty < 0)
  159.                 {
  160.                         ty += N;
  161.                 }
  162.                 while (tx < 0)
  163.                 {
  164.                         tx += N;
  165.                 }
  166.                 if (tx == 0 && ty != 0)
  167.                 {
  168.                         flag = 1;
  169.                 }
  170.                 else
  171.                 {
  172.                         t = ty * inverse(N, tx) % N;
  173.                 }
  174.         }
  175.         if (flag == 1)
  176.         {
  177.                 p2.x = -1;
  178.                 p2.y = -1;
  179.         }
  180.         else
  181.         {
  182.                 x3 = (t * t - x1 - x2) % N;
  183.                 y3 = (t * (x1 - x3) - y1) % N;
  184.                 //使结果在有限域GF(P)上
  185.                 while (x3 < 0)
  186.                 {
  187.                         x3 += N;
  188.                 }
  189.                 while (y3 < 0)
  190.                 {
  191.                         y3 += N;
  192.                 }
  193.                 p2.x = x3;
  194.                 p2.y = y3;
  195.         }
  196.         return p2;
  197. }
  198. //task2:倍点运算的递归算法
  199. Point timesPiont(int k, Point p0)
  200. {
  201.         if (k == 1)
  202.         {
  203.                 return p0;
  204.         }
  205.         else if (k == 2)
  206.         {
  207.                 return add_two_points(p0, p0);
  208.         }
  209.         else
  210.         {
  211.                 return add_two_points(p0, timesPiont(k - 1, p0));
  212.         }
  213. }
  214. main(){
  215.         get_generetor_class();
  216.         Point p1, p2, p, p4, p5, p6, p7, p8, p9, p10;
  217.         int na, k, h, r, s, u1, u2;
  218.         printf("选择生成元");
  219.         scanf("%d%d", &p1.x, &p1.y);
  220.         int j = 0;
  221.         while (j < N)
  222.         {

  223.                 if (geneSet[j].p.x == p1.x && geneSet[j].p.y == p1.y)
  224.                 {
  225.                         break;
  226.                 }
  227.                 printf("j=%d\n", j);
  228.                 ++j;
  229.         }
  230.         int M = geneSet[j].p_class;
  231.         printf("M=%d", M);
  232.         //        p1.x=0;
  233.         //        p1.y=2;
  234.         //p.x=20;
  235.         //p.y=1;
  236.         printf("请输入私钥");
  237.         scanf("%d", &na);
  238.         p2 = eccmutiply(na, p1);
  239.         printf("公钥为(%d,%d)", p2.x, p2.y);
  240.         //p2=mul(p,p1);

  241.         //printf("(%d,%d)",p2.x,p2.y);

  242.         //签名过程
  243.         printf("输入随机数k\n");
  244.         scanf("%d", &k);
  245.         printf("输入hash\n");
  246.         scanf("%d", &h);


  247.         p4 = eccmutiply(k, p1);
  248.         r = calculate3(p4.x, 1, N);
  249.         if (r < 0) r = r + N;
  250.         s = inverse(M, k) * (h + na * r) % M;
  251.         if (s < 0) s = s + N;
  252.         printf("签名为(%d,%d)\n", r, s);
  253.         printf("========================");
  254.         //验证过程
  255.         u1 = h * inverse(M, s) % M;

  256.         if (u1 < 0) u1 = u1 + M;
  257.         u2 = r * inverse(M, s) % M;

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

  259.         printf("u1u2=%d,%d\n", u1, u2);

  260.         p5 = eccmutiply(u1, p1);
  261.         printf("sG=(%d,%d)\n", p5.x, p5.y);

  262.         p6 = eccmutiply(u2, p2);
  263.         printf("HP=(%d,%d)\n", p6.x, p6.y);

  264.         p7 = add_two_points(p5, p6);
  265.         printf("sG+HP=(%d,%d)\n", p7.x, p7.y);
  266.         if (calculate3(p7.x, 1, N) == r)
  267.         {
  268.                 printf("通过");
  269.         }
  270.         else
  271.         {
  272.                 printf("失败");
  273.         }

  274. }
复制代码
回复

使用道具 举报

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

本版积分规则

教学服务系统

GMT+8, 2025-4-30 02:03 , Processed in 0.021771 second(s), 29 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

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