教学服务系统

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

信息计算2019级2班15号陈周易

[复制链接]

9

主题

21

帖子

99

积分

注册会员

Rank: 2

积分
99
发表于 2022-6-2 13:04:28 | 显示全部楼层 |阅读模式
RSA加密原理

RSA加密是一种非对称加密。可以在不直接传递密钥的情况下,完成解密。是由一对密钥来进行加解密的过程,分别称为公钥和私钥。传递时只传递公钥,不传递私钥。⽤私钥加密的内容只能⽤对应的公钥解密,反之⽤公钥加密的内容只能⽤对应的私钥解密。
RSA加密过程
   A向B发送信息:A⽤⾃⼰的私钥加密,B只能⽤A的公钥解密。
   B向A发送信息:B⽤A的公钥加密数据,A只能⽤⾃⼰的私钥解密
RSA签名的过程
   A生成一对密钥(公钥和私钥),私钥不公开,A自己保留。公钥为公开的,任何人可以获取。
   A用自己的私钥对消息加签,形成签名,并将加签的消息和消息本身一起传递给B。
   B收到消息后,在获取A的公钥进行验签,如果验签出来的内容与消息本身一致,证明消息是A回复的。
  在这个过程中,只有2次传递过程,第一次是A传递加签的消息和消息本身给B,第二次是B获取A的公钥,即使都被敌方截获,也没有危险性,因为只有A的私钥才能对消息进行签名,即使知道了消息内容,也无法伪造带签名的回复给B,防止了消息内容的篡改。
代码如下:
  1. import java.io.ByteArrayOutputStream;
  2. import java.security.KeyFactory;
  3. import java.security.KeyPair;
  4. import java.security.KeyPairGenerator;
  5. import java.security.PrivateKey;
  6. import java.security.PublicKey;
  7. import java.security.Signature;
  8. import java.security.spec.PKCS8EncodedKeySpec;
  9. import java.security.spec.X509EncodedKeySpec;
  10. import javax.crypto.Cipher;
  11. import org.apache.commons.codec.binary.Base64;

  12. public class TestRSA {

  13.     /**
  14.      * RSA最大加密明文大小
  15.      */
  16.     private static final int MAX_ENCRYPT_BLOCK = 64;

  17.     /**
  18.      * RSA最大解密密文大小
  19.      */
  20.     private static final int MAX_DECRYPT_BLOCK = 75;

  21.     /**
  22.      * 获取密钥对
  23.      *
  24.      * @return 密钥对
  25.      */
  26.     public static KeyPair getKeyPair() throws Exception {
  27.         KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");
  28.         generator.initialize(512);
  29.         return generator.generateKeyPair();
  30.     }

  31.     /**
  32.      * 获取私钥
  33.      *
  34.      * @param privateKey 私钥字符串
  35.      * @return
  36.      */
  37.     public static PrivateKey getPrivateKey(String privateKey) throws Exception {
  38.         KeyFactory keyFactory = KeyFactory.getInstance("RSA");
  39.         byte[] decodedKey = Base64.decodeBase64(privateKey.getBytes());
  40.         PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(decodedKey);
  41.         return keyFactory.generatePrivate(keySpec);
  42.     }

  43.     /**
  44.      * 获取公钥
  45.      *
  46.      * @param publicKey 公钥字符串
  47.      * @return
  48.      */
  49.     public static PublicKey getPublicKey(String publicKey) throws Exception {
  50.         KeyFactory keyFactory = KeyFactory.getInstance("RSA");
  51.         byte[] decodedKey = Base64.decodeBase64(publicKey.getBytes());
  52.         X509EncodedKeySpec keySpec = new X509EncodedKeySpec(decodedKey);
  53.         return keyFactory.generatePublic(keySpec);
  54.     }

  55.     /**
  56.      * RSA加密
  57.      *
  58.      * @param data 待加密数据
  59.      * @param publicKey 公钥
  60.      * @return
  61.      */
  62.     public static String encrypt(String data, PublicKey publicKey) throws Exception {
  63.         Cipher cipher = Cipher.getInstance("RSA");
  64.         cipher.init(Cipher.ENCRYPT_MODE, publicKey);
  65.         int inputLen = data.getBytes().length;
  66.         ByteArrayOutputStream out = new ByteArrayOutputStream();
  67.         int offset = 0;
  68.         byte[] cache;
  69.         int i = 0;
  70.         // 对数据分段加密
  71.         while (inputLen - offset > 0) {
  72.             if (inputLen - offset > MAX_ENCRYPT_BLOCK) {
  73.                 cache = cipher.doFinal(data.getBytes(), offset, MAX_ENCRYPT_BLOCK);
  74.             } else {
  75.                 cache = cipher.doFinal(data.getBytes(), offset, inputLen - offset);
  76.             }
  77.             out.write(cache, 0, cache.length);
  78.             i++;
  79.             offset = i * MAX_ENCRYPT_BLOCK;
  80.         }
  81.         byte[] encryptedData = out.toByteArray();
  82.         out.close();
  83.         // 获取加密内容使用base64进行编码,并以UTF-8为标准转化成字符串
  84.         // 加密后的字符串
  85.         return new String(Base64.encodeBase64String(encryptedData));
  86.     }

  87.     /**
  88.      * RSA解密
  89.      *
  90.      * @param data 待解密数据
  91.      * @param privateKey 私钥
  92.      * @return
  93.      */
  94.     public static String decrypt(String data, PrivateKey privateKey) throws Exception {
  95.         Cipher cipher = Cipher.getInstance("RSA");
  96.         cipher.init(Cipher.DECRYPT_MODE, privateKey);
  97.         byte[] dataBytes = Base64.decodeBase64(data);
  98.         int inputLen = dataBytes.length;
  99.         ByteArrayOutputStream out = new ByteArrayOutputStream();
  100.         int offset = 0;
  101.         byte[] cache;
  102.         int i = 0;
  103.         // 对数据分段解密
  104.         while (inputLen - offset > 0) {
  105.             if (inputLen - offset > MAX_DECRYPT_BLOCK) {
  106.                 cache = cipher.doFinal(dataBytes, offset, MAX_DECRYPT_BLOCK);
  107.             } else {
  108.                 cache = cipher.doFinal(dataBytes, offset, inputLen - offset);
  109.             }
  110.             out.write(cache, 0, cache.length);
  111.             i++;
  112.             offset = i * MAX_DECRYPT_BLOCK;
  113.         }
  114.         byte[] decryptedData = out.toByteArray();
  115.         out.close();
  116.         // 解密后的内容
  117.         return new String(decryptedData, "UTF-8");
  118.     }

  119.     /**
  120.      * 签名
  121.      *
  122.      * @param data 待签名数据
  123.      * @param privateKey 私钥
  124.      * @return 签名
  125.      */
  126.     public static String sign(String data, PrivateKey privateKey) throws Exception {
  127.         byte[] keyBytes = privateKey.getEncoded();
  128.         PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
  129.         KeyFactory keyFactory = KeyFactory.getInstance("RSA");
  130.         PrivateKey key = keyFactory.generatePrivate(keySpec);
  131.         Signature signature = Signature.getInstance("MD5withRSA");
  132.         signature.initSign(key);
  133.         signature.update(data.getBytes());
  134.         return new String(Base64.encodeBase64(signature.sign()));
  135.     }

  136.     /**
  137.      * 验签
  138.      *
  139.      * @param srcData 原始字符串
  140.      * @param publicKey 公钥
  141.      * @param sign 签名
  142.      * @return 是否验签通过
  143.      */
  144.     public static boolean verify(String srcData, PublicKey publicKey, String sign) throws Exception {
  145.         byte[] keyBytes = publicKey.getEncoded();
  146.         X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
  147.         KeyFactory keyFactory = KeyFactory.getInstance("RSA");
  148.         PublicKey key = keyFactory.generatePublic(keySpec);
  149.         Signature signature = Signature.getInstance("MD5withRSA");
  150.         signature.initVerify(key);
  151.         signature.update(srcData.getBytes());
  152.         return signature.verify(Base64.decodeBase64(sign.getBytes()));
  153.     }
  154. }
  155. public static void main(String[] args) {
  156.         try {
  157.             // 生成密钥对
  158.             KeyPair keyPair = getKeyPair();
  159.             String privateKey = new String(Base64.encodeBase64(keyPair.getPrivate().getEncoded()));
  160.             String publicKey = new String(Base64.encodeBase64(keyPair.getPublic().getEncoded()));
  161.             System.out.println("私钥:" + privateKey);
  162.             System.out.println("公钥:" + publicKey);
  163.             // RSA加密 待加密的文字内容
  164.             String data = "123456";
  165.             String encryptData = encrypt(data, getPublicKey(publicKey));
  166.             System.out.println("加密前内容:" + data);
  167.             System.out.println("加密后内容:" + encryptData);
  168.             // RSA解密
  169.             String decryptData = decrypt(encryptData, getPrivateKey(privateKey));
  170.             System.out.println("解密后内容:" + decryptData);

  171.             // RSA签名
  172.             String sign = sign(data, getPrivateKey(privateKey));
  173.             // RSA验签
  174.             boolean result = verify(data, getPublicKey(publicKey), sign);
  175.             System.out.print("验签结果:" + result);
  176.         } catch (Exception e) {
  177.             e.printStackTrace();
  178.             System.out.print("加解密异常");
  179.         }
  180. }
复制代码





回复

使用道具 举报

9

主题

21

帖子

99

积分

注册会员

Rank: 2

积分
99
 楼主| 发表于 2022-6-2 13:05:43 | 显示全部楼层
椭圆曲线密码算法(ECCECC加密原理:
1、用户A选定一条适合加密的椭圆曲线Ep(a,b)(:y2=x3+ax+b),并取椭圆曲线上一点,作为基点G
 2、用户A选择一个私有密钥k,并生成公开密钥K=kG
 3、用户AEp(a,b)和点KG传给用户B
 4、用户B接到信息后 ,将待传输的明文编码到Ep(a,b)上一点M,并产生一个随机整数rr<n)。
 5、用户B计算点C1=M+rKC2=rG
 6、用户BC1C2传给用户A
 7、用户A接到信息后,计算C1-kC2,结果就是点M。因为
          C1-kC2=M+rK-k(rG)=M+rK-r(kG)=M
   再对点M进行解码就可以得到明文。
代码:
  1. #include <iostream>
  2. #define Ea 20
  3. #define Eb 4
  4. #define Ep 29
  5. using namespace std;
  6. int fast_pow(int a, int b, int c)
  7. {
  8.     int ans = 1;   ///记录结果
  9.     a = a % c;   ///预处理,使得a处于c的数据范围之下
  10.     while (b != 0)
  11.     {
  12.         if (b & 1)///奇数
  13.         {
  14.             ans = (ans * a) % c;///消除指数为奇数的影响
  15.         }
  16.         b >>= 1;    ///二进制的移位操作,不断的遍历b的二进制位
  17.         a = (a * a) % c;   ///不断的加倍
  18.     }
  19.     return ans;
  20. }
  21. struct point {
  22.     int x;
  23.     int y;
  24.     point() :x(0), y(0) {}
  25.     point(int a, int b) :x(a), y(b) { }
  26.     bool operator==(const point& b) {
  27.         return this->x == b.x && this->y == b.y;
  28.     }
  29.     point operator+(const point& b) {
  30.         point result;
  31.         if (*this == b) {
  32.             long aaa = 3 * this->x * this->x + Ea;
  33.             long bbb = 2 * this->y;
  34.             //int m = (3 * this->x * this->x + Ea) / (2 * this->y) mod Ep;
  35.             long m;
  36.             if (aaa % bbb != 0) {
  37.                 m = ((aaa % Ep) * fast_pow(bbb, (Ep - 2), Ep)) % Ep;
  38.             }
  39.             else {
  40.                 m = (aaa / bbb) % Ep;
  41.             }
  42.             result.x = (m * m - 2 * this->x) % Ep;
  43.             result.y = (m * (this->x - result.x) - this->y) % Ep;
  44.         }
  45.         else {
  46.             long aaa = b.y - this->y;
  47.             long bbb = b.x - this->x;
  48.             if (bbb == 0) {
  49.                 return point(13, 23);
  50.             }
  51.             long m;
  52.             if (aaa % bbb != 0) {
  53.                 m = ((aaa % Ep) * fast_pow(bbb, (Ep - 2), Ep)) % Ep;
  54.             }
  55.             else {
  56.                 m = (aaa / bbb) % Ep;
  57.             }
  58.             result.x = (m * m - this->x - b.x) % Ep;
  59.             result.y = (m * (this->x - result.x) - this->y) % Ep;
  60.         }
  61.         if (result.x < 0) {
  62.             result.x += Ep;
  63.         }
  64.         if (result.y < 0) {
  65.             result.y += Ep;
  66.         }
  67.         return result;
  68.     }
  69.     point operator-() {
  70.         this->y = Ep - this->y;
  71.         return *this;
  72.     }
  73. };
  74. void getG(point x, int& G) {
  75.     point Gx = x;
  76.     G = 1;
  77.     int num = 0;
  78.     do {
  79.         cout << G << "x:" << Gx.x << " " << Gx.y << endl;
  80.         Gx = Gx + x;
  81.         G++;
  82.     } while (Gx.x != x.x);
  83.     G++;
  84.     cout << G << "x:" << Gx.x << " " << Gx.y << endl;
  85. }
  86. point getNG(point x, int n) {
  87.     point result = x;
  88.     for (int i = 1; i < n; ++i) {
  89.         result = result + x;
  90.     }

  91.     return result;
  92. }
  93. void print(point p) {
  94.     cout << "[" << " " << p.x << "," << p.y << " " << "]" << endl;
  95. }
  96. int main()
  97. {
  98.     //Alice
  99.     //椭圆曲线 E29(20,4) 基点(13,23)
  100.     //第一步,计算椭圆曲线的阶数
  101.     int G;
  102.     point* x = new point(13, 23);
  103.     getG(*x, G);
  104.     cout << "阶数为:" << G << endl;
  105.     //求得G=36
  106.     //第二步,选择一个私有密钥p(p<G)
  107.     int p = 25;
  108.     //第三步,公开密钥K=p*(13,23)
  109.     point K = getNG(*x, p);
  110.     //将 曲线 基点 密钥 公开
  111.     cout << "公开密钥:" << endl;
  112.     print(K);
  113.     //Bob
  114.     //第四步,需要加密的信息msg,并将msg按照某种编码方式编码到曲线上一点M
  115.     int msg = 13;
  116.     cout << "需要加密的信息:" << msg << endl;;
  117.     point M(13, 23);

  118.     //第五步,产生一个随机数r<G
  119.     //srand(unsigned(time(NULL)));
  120.     int r = 6;
  121.     //第六步,计算c1=M+r*K
  122.     //           c2=r*(13,23)
  123.     //(c1,c2)
  124.     point c1 = M;
  125.     for (int i = 0; i < r; ++i) {
  126.         c1 = c1 + K;
  127.     }
  128.     point c2 = *x;
  129.     for (int i = 1; i < r; ++i) {
  130.         c2 = c2 + *x;
  131.     }
  132.     cout << "密文为:" << endl;;
  133.     print(c1);
  134.     print(c2);

  135.     //Alice解密
  136.     //第七步:计算c1-p*c2
  137.     point c3;
  138.     point c4 = *x;
  139.     p = p * r % G;
  140.     for (int i = 1; i < p; ++i) {
  141.         c4 = c4 + *x;
  142.     }
  143.     c3 = c1 + (-c4);
  144.     cout << "明文为:" << c3.x << endl;
  145.     return 0;
  146. }
复制代码


回复

使用道具 举报

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

本版积分规则

教学服务系统

GMT+8, 2025-4-30 07:43 , Processed in 0.014747 second(s), 18 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

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