教学服务系统

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

信息计算2019级1班27号许鹏程

[复制链接]

8

主题

23

帖子

110

积分

注册会员

Rank: 2

积分
110
发表于 2022-6-2 12:07:09 | 显示全部楼层 |阅读模式
ECC椭圆曲线加解密

ECC是一种基于椭圆曲线数学的公开密钥加密算法,其本质是利用离散对数问题实现加密。一条椭圆曲线就是一组被 y^2 = x^3 + ax + b 定义的且满足 4a^3 + 27b^2 ≠ 0 的点集。

ECC技术要求
通常将Fp上的一条椭圆曲线描述为T=(p,a,b,G,n,h)p、a、b确定一条椭圆曲线(p为质数,(mod p)运算)G为基点,n为点G的阶,h是椭圆曲线上所有点的个数m与n相除的商的整数部分

参量选择要求:

p越大安全性越好,但会导致计算速度变慢
200-bit左右可满足一般安全要求
n应为质数
h≤4;p≠n×h ;pt≠1(mod n) (1≤t<20)
4a3+27b2≠0 (mod p)



回复

使用道具 举报

8

主题

23

帖子

110

积分

注册会员

Rank: 2

积分
110
 楼主| 发表于 2022-6-2 12:07:29 | 显示全部楼层
  1. #pragma once
  2. #include <vector>
  3. #include "stdafx.h"
  4. #include "Key.h"
  5. #include "StdAfx.h"
  6. #include "ECC.h"
  7. #include <math.h>
  8. #include <sstream>
  9. #include <stdlib.h>
  10. #include <string>
  11. #include <iomanip>


  12. class ECC
  13. {
  14. public:
  15.         ECC(int a,int b,int p);
  16.         virtual ~ECC(void);
  17.         void encrypt(const std::vector<Point> &Pm,Key &key,std::vector<Cipher> &result,int k=-1);

  18.         void decrypt(const std::vector<Cipher>& ciphers,int x,std::vector<Point> &result);
  19.         const std::vector<Generator> getGenerators()const;
  20.         void genKey(Key& result,int gIndex=-1,int x=-1);

  21.         void decodePlainPoints(const std::vector<Point>& Pm,std::string &result);

  22.         void encodePlainText(const char* plainText,std::vector<Point> &result);
  23.         static bool isPrime(int n);
  24. protected:
  25.         int mA,mB,mP;
  26.         std::vector<Point> mPoints;
  27.         std::vector<Generator> mGenerators;
  28.         Dictionary mDictionary;
  29. private:
  30.         void getAllPoints();
  31.         void getAllOrders();
  32.         int getOrder(const Point&p);
  33.         int ex_gcd(int a,int b,int& x,int& y);
  34.         int getInverse(int a,int p);
  35.         Point getMultiplePoint(int k,const Point& p);
  36.         Point add(const Point& p1,const Point& p2);
  37.         int mod(int a,int p);
  38. };



  39. ECC::ECC(int a = 4, int b = 20, int p = 29)
  40. {
  41.         this->mA = a;
  42.         this->mB = b;
  43.         this->mP = p;
  44.         this->getAllPoints();
  45.         this->getAllOrders();
  46. }

  47. ECC::~ECC(void)
  48. {
  49. }

  50. void ECC::getAllPoints()
  51. {
  52.         int left, right = 0;
  53.         for (int x = 0; x < mP; x++)
  54.         {
  55.                 right = x * x * x + mA * x + mB;
  56.                 for (int y = 0; y < mP; y++)
  57.                 {
  58.                         left = y * y;
  59.                         if (mod(left, mP) == mod(right, mP))
  60.                         {
  61.                                 mPoints.push_back(Point(x, y));
  62.                         }
  63.                 }
  64.         }
  65. }


  66. class Key
  67. {
  68. public:
  69.         Key(void);
  70.         Key(const Generator& g, int x, const Point& Q);//生成元g,私钥x,公钥Q
  71.         virtual ~Key(void);
  72.         const Point& getPublicKey()const;
  73.         const int getPrivateKey()const;
  74.         const Generator& getGenerator()const;
  75. protected:
  76.         Generator m_g;//生成元
  77.         Point m_Q;//公钥
  78.         int m_x;//私钥
  79. };


  80. void ECC::getAllOrders()
  81. {
  82.         for (std::vector<Point>::const_iterator it = mPoints.begin(); it != mPoints.end(); it++)
  83.         {
  84.                 mGenerators.push_back(Generator(*it, getOrder(*it)));
  85.         }
  86. }
  87. int ECC::getOrder(const Point& p)
  88. {
  89.         int i = 1;
  90.         Point q = add(p, p);
  91.         while (q != p && q.isInfinity() == false)
  92.         {
  93.                 i++;
  94.                 q = add(p, q);
  95.         }
  96.         return ++i;
  97. }
  98. int ECC::ex_gcd(int a, int b, int& x, int& y)
  99. {
  100.         if (b == 0)
  101.         {
  102.                 x = 1;
  103.                 y = 0;
  104.                 return a;
  105.         }
  106.         int ans = this->ex_gcd(b, a % b, x, y);
  107.         int tmp = x;
  108.         x = y;
  109.         y = tmp - a / b * y;
  110.         return ans;
  111. }

  112. int ECC::getInverse(int a, int p)
  113. {
  114.         int x, y;
  115.         int n = ex_gcd(a, p, x, y);
  116.         if (1 % n != 0) return -1;
  117.         x *= 1 / n;
  118.         p = abs(p);
  119.         int ans = x % p;
  120.         if (ans <= 0) ans += p;
  121.         return ans;
  122. }

  123. Point ECC::getMultiplePoint(int k, const Point& p)
  124. {
  125.         Point q(p);
  126.         for (int i = 1; i < k; i++)
  127.         {
  128.                 q = add(p, q);
  129.         }
  130.         return q;
  131. }

  132. Point ECC::add(const Point& p, const Point& q)
  133. {
  134.         int lambda, m, n;
  135.         int x, y;
  136.         if (p.isInfinity())
  137.         {
  138.                 return q;
  139.         }
  140.         if (q.isInfinity())
  141.         {
  142.                 return p;
  143.         }
  144.         if (p == q)
  145.         {
  146.                 m = mod(3 * p.X * p.X + mA, mP);
  147.                 n = mod(2 * p.Y, mP);

  148.         }
  149.         else//P≠Q
  150.         {
  151.                 m = mod(q.Y - p.Y, mP);
  152.                 n = mod(q.X - p.X, mP);

  153.         }
  154.         if (n == 0)
  155.         {
  156.                 return Point::Infinity();
  157.         }
  158.         lambda = mod(m * getInverse(n, mP), mP);
  159.         x = mod(lambda * lambda - p.X - q.X, mP);
  160.         y = mod(lambda * (p.X - x) - p.Y, mP);
  161.         return Point(x, y);
  162. }

  163. int ECC::mod(int a, int p)
  164. {
  165.         if (a >= 0)
  166.         {
  167.                 return a % p;
  168.         }
  169.         else
  170.         {
  171.                 return ((a % p) + p) % p;
  172.         }
  173. }

  174. void ECC::encrypt(const std::vector<Point>& Pm, Key& key, std::vector<Cipher>& result, int k)
  175. {
  176.         bool flag = k <= 1 || k > key.getGenerator().Order;

  177.         for (std::vector<Point>::const_iterator it = Pm.begin(); it != Pm.end(); it++)
  178.         {
  179.                 if (flag)
  180.                 {
  181.                         k = rand() % (key.getGenerator().Order - 1) + 1;
  182.                 }
  183.                 Point C1 = getMultiplePoint(k, key.getGenerator().Value);
  184.                 Point C2 = add(*it, getMultiplePoint(k, key.getPublicKey()));
  185.                 result.push_back(Cipher(C1, C2));
  186.         }
  187. }

  188. void ECC::encodePlainText(const char* plainText, std::vector<Point>& result)
  189. {
  190.         mDictionary = Dictionary(plainText);
  191.         while (*plainText != '\0')
  192.         {
  193.                 int index = mDictionary.getIndex(*plainText);
  194.                 result.push_back(mPoints[index]);
  195.                 plainText++;
  196.         }
  197. }
  198. void ECC::decodePlainPoints(const std::vector<Point>& Pm, std::string& result)
  199. {
  200.         std::stringstream ss;
  201.         for (std::vector<Point>::const_iterator it = Pm.begin(); it != Pm.end(); it++)
  202.         {
  203.                 for (unsigned int i = 0; i < mPoints.size(); i++)
  204.                 {
  205.                         if (mPoints[i] == *it)
  206.                         {
  207.                                 unsigned char ch = mDictionary.getChar(i);
  208.                                 ss << ch;
  209.                                 break;
  210.                         }
  211.                 }
  212.         }
  213.         ss >> result;
  214. }
  215. void ECC::decrypt(const std::vector<Cipher>& ciphers, int x, std::vector<Point>& result)
  216. {
  217.         for (std::vector<Cipher>::const_iterator it = ciphers.begin(); it != ciphers.end(); it++)
  218.         {
  219.                 Point C1R = Point(it->C1.X, -it->C1.Y);
  220.                 Point Pm = add(it->C2, getMultiplePoint(x, C1R));
  221.                 result.push_back(Pm);
  222.         }
  223. }
  224. bool ECC::isPrime(int n)
  225. {
  226.         if (n < 2)
  227.                 return false;
  228.         if (n == 2 || n == 3)
  229.                 return true;
  230.         if (n % 6 != 1 && n % 6 != 5)
  231.                 return false;
  232.         float n_sqrt = floor(sqrt((float)n));
  233.         for (int i = 5; i <= n_sqrt; i += 6)
  234.         {
  235.                 if (n % i == 0 || n % (i + 2) == 0)
  236.                         return false;
  237.         }
  238.         return true;
  239. }
  240. //g是生成元,x是私钥
  241. void ECC::genKey(Key& result, int gIndex, int x)
  242. {
  243.         int n;
  244.         Generator G;
  245.         if (gIndex < 0 || isPrime(mGenerators[gIndex].Order) == false)
  246.         {
  247.                 do
  248.                 {
  249.                         gIndex = rand() % mGenerators.size();
  250.                         n = mGenerators[gIndex].Order;
  251.                 } while (isPrime(n) == false);
  252.         }
  253.         else
  254.         {
  255.                 n = mGenerators[gIndex].Order;
  256.         }
  257.         G = mGenerators[gIndex];
  258.         if (x >= n || x <= 1)
  259.         {
  260.                 x = rand() % (n - 1) + 1;
  261.         }
  262.         Point Q = getMultiplePoint(x, G.Value);
  263.         result = Key(G, x, Q);
  264. }
  265. const std::vector<Generator> ECC::getGenerators()const
  266. {
  267.         return mGenerators;
  268. }



  269. Key::Key(const Generator& g, int x, const Point& Q)
  270. {
  271.         this->m_g = g;
  272.         this->m_Q = Q;
  273.         this->m_x = x;
  274. }
  275. Key::Key(void)
  276. {

  277. }

  278. Key::~Key(void)
  279. {
  280. }

  281. const Point& Key::getPublicKey()const
  282. {
  283.         return m_Q;
  284. }

  285. const int Key::getPrivateKey()const
  286. {
  287.         return m_x;
  288. }
  289. const Generator& Key::getGenerator()const
  290. {
  291.         return m_g;
  292. }




  293. using namespace std;

  294. template <typename T>
  295. void print(const vector<T>& list)
  296. {
  297.         for (unsigned int i = 0; i < list.size(); i++)
  298.         {
  299.                 if (i % 4 == 0)
  300.                 {
  301.                         cout << endl;
  302.                 }
  303.                 cout << setw(3) << setfill(' ') << i << "、" << list[i] << "\t\t";
  304.         }
  305.         cout << endl;
  306.         cout << "-------------------------------------------------------" << endl;
  307. }

  308. int main()
  309. {
  310.         int a, b, p, x, k;
  311.         Key key;
  312.         cout << "椭圆曲线方程为:" << "y^2 = x^3 + ax + b (mod p)" << endl;
  313.         //选取方程参数
  314. input:        cout << "请输入a的值(a是整数,a>0):";
  315.         cin >> a;
  316.         cout << "请输入b的值(b是整数,b>0):";
  317.         cin >> b;
  318.         cout << "请输入p的值(p是大素数,但目前用Int32表示):";
  319.         cin >> p;
  320.         if (ECC::isPrime(p) == false)
  321.         {
  322.                 cout << "p不是素数,请重新输入!" << endl;
  323.                 goto input;
  324.         }
  325.         if ((4 * (a * a * a) + 27 * (b * b)) % p == 0)
  326.         {//当4a^3+27b^2≠0时,是一条非奇异椭圆曲线,此时可以在E(a,b)定义一个阿贝尔群
  327.                 cout << "输入的参数有误,请重新输入!" << endl;
  328.                 goto input;
  329.         }
  330.         //初始化椭圆曲线方程
  331.         ECC ecc(a, b, p);
  332.         //获取所有生成元以及对应的阶
  333.         vector<Generator> generators = ecc.getGenerators();
  334.         cout << "下面是生成元及对应的阶数:" << endl;
  335.         print(generators);
  336.         //选择基点G
  337.         cout << "请选择基点G(x,y)的序号:";//G=P
  338.         cin >> k;
  339.         //输入私钥
  340.         cout << "请输入私钥(x<" << generators[k].Order << "):x = ";
  341.         cin >> x;
  342.         //产生公私钥对
  343.         ecc.genKey(key, k, x);
  344.         if (generators[k] != key.getGenerator())
  345.         {
  346.                 cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << endl;
  347.                 cout << "你选择的生成元为:G = " << generators[k] << endl;
  348.                 cout << "该生成元的阶数为:ord(G) = " << generators[k].Order << ",不是素数" << endl;
  349.                 cout << "生成元已自动变更为:G = " << key.getGenerator() << endl;
  350.                 cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << endl;
  351.         }
  352.         cout << "生成的公钥为:Q = " << key.getPublicKey() << endl;
  353.         cout << "目前的私钥为:x = " << key.getPrivateKey() << endl;
  354.         //输入随机数k
  355.         cout << "请输入k的值来计算 kG,kQ+Pm,输入负数使用随机值(1<k<" << key.getGenerator().Order << "):k = ";
  356.         cin >> k;

  357.         vector<Point> encodedPoints;
  358.         vector<Cipher> cipheredPoints;
  359.         //将明文m编码为椭圆曲线上的点
  360.         ecc.encodePlainText("Hello,我是明文", encodedPoints);
  361.         cout << "编码后的明文点集为:Pme = " << endl;
  362.         print(encodedPoints);
  363.         //加密
  364.         ecc.encrypt(encodedPoints, key, cipheredPoints, k);
  365.         cout << "加密后的密文点集为:Pc = " << endl;
  366.         print(cipheredPoints);

  367.         vector<Point> decryptedPoints;
  368.         string decodedText;
  369.         //解密
  370.         ecc.decrypt(cipheredPoints, key.getPrivateKey(), decryptedPoints);
  371.         cout << "解密后的明文点集为:Pm = " << endl;
  372.         print(decryptedPoints);
  373.         //解码明文点集,得到明文字符串
  374.         ecc.decodePlainPoints(decryptedPoints, decodedText);
  375.         cout << "解码后的字符串明文为:" << endl;
  376.         cout << decodedText << endl;
  377.         system("Pause");
  378.         return 0;
  379. }

复制代码
回复

使用道具 举报

8

主题

23

帖子

110

积分

注册会员

Rank: 2

积分
110
 楼主| 发表于 2022-6-2 14:39:49 | 显示全部楼层
RSA签名


RSA 数字签名算法(RSASA)的本质,仍然是 RSA 加密/解密算法.
RSA签名分为两步:
1)将待签名的 M 进行 Hash,从而得到 H
2)将 H 进行 RSA 私钥加密.

RSA签名的过程如下:

  (1)A⽣成⼀对密钥(公钥和私钥),私钥不公开,A⾃⼰保留。公钥为公开的,任何⼈可以获取。

  (2)A⽤⾃⼰的私钥对消息加签,形成签名,并将加签的消息和消息本⾝⼀起传递给B。

  (3)B收到消息后,在获取A的公钥进⾏验签,如果验签出来的内容与消息本⾝⼀致,证明消息是A回复的。
回复

使用道具 举报

8

主题

23

帖子

110

积分

注册会员

Rank: 2

积分
110
 楼主| 发表于 2022-6-2 14:45:47 | 显示全部楼层

  1. import javax.crypto.Cipher;
  2. import netscape.javascript.JSException;
  3. import java.io.ByteArrayOutputStream;
  4. import java.security.*;
  5. import java.security.spec.PKCS8EncodedKeySpec;
  6. import java.security.spec.X509EncodedKeySpec;
  7. import java.util.Map;


  8. public class RsaUtils {

  9.     public static final String Encryption = "RSA";

  10.     public static final String Privatesignature = "SHA256withRSA";

  11.     private static final int MAX_ENCRYPT_BLOCK = 245 ;

  12.     private static final int MAX_DECRYPT_BLOCK = 256;

  13.     public static void main(String[] args) throws  Exception{


  14.         String publicKey = "rsa_public_key.pem 公钥内容";

  15.         String privateKey = "pkcs8_rsa_private_key.pem中密钥内容";

  16.         try {
  17.             
  18.             System.out.println("私钥:" + privateKey);
  19.             System.out.println("公钥:" + publicKey);

  20.             String data = "{"user_name":"张三","password":"666666"}";
  21.             String encryptData = encrypt(data, getPublicKey(publicKey));
  22.             System.out.println("加密后内容:" + encryptData);


  23.             String decryptData = decrypt(encryptData, getPrivateKey(privateKey));
  24.             System.out.println("解密后内容:" + decryptData);

  25.             String sign = sign(data, getPrivateKey(privateKey));
  26.             System.out.println("签名后结果:" + decryptData);
  27.    
  28.             boolean result = verify(data, getPublicKey(publicKey), sign);
  29.             System.out.print("验签结果:" + result);
  30.         } catch (Exception e) {
  31.             e.printStackTrace();
  32.             System.out.print("加解密异常");
  33.         }

  34.     }


  35.    
  36.     public static String dnRSA(String tslPublicKey,String privateKey,String pamStr,String sign) throws Exception {
  37.         if(verify(pamStr, getPublicKey(tslPublicKey), sign)){
  38.             String result = decrypt(pamStr, getPrivateKey(privateKey));
  39.             return result;
  40.         }else{
  41.             return null;
  42.         }
  43.     }

  44.     public static KeyPair getKeyPair() throws Exception {
  45.         KeyPairGenerator generator = KeyPairGenerator.getInstance(Encryption);
  46.         generator.initialize(1024);
  47.         return generator.generateKeyPair();
  48.     }

  49.     public static PrivateKey getPrivateKey(String privateKey) throws Exception {
  50.         KeyFactory keyFactory = KeyFactory.getInstance(Encryption);
  51.         byte[] decodedKey = Base64.decodeBase64(privateKey.getBytes());
  52.         PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(decodedKey);
  53.         return keyFactory.generatePrivate(keySpec);
  54.     }

  55.     public static JSONObject enRSAjson(String publicKey,String thirdPrivateKey,String pamStr) throws Exception {
  56.         JSONObject json = new JSONObject();
  57.         String encryptData = encrypt(pamStr, getPublicKey(publicKey));

  58.         String sign = sign(encryptData, getPrivateKey(thirdPrivateKey));
  59.         json.put("payload",encryptData);
  60.         json.put("sign",sign);
  61.         return json;
  62.     }

  63.     public static PublicKey getPublicKey(String publicKey) throws Exception {
  64.         KeyFactory keyFactory = KeyFactory.getInstance(Encryption);
  65.         byte[] decodedKey = Base64.decodeBase64(publicKey.getBytes());
  66.         X509EncodedKeySpec keySpec = new X509EncodedKeySpec(decodedKey);
  67.         return keyFactory.generatePublic(keySpec);
  68.     }


  69.     public static String encrypt(String data, PublicKey publicKey) throws Exception {
  70.         Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
  71.         cipher.init(Cipher.ENCRYPT_MODE, publicKey);
  72.         int inputLen = data.getBytes().length;
  73.         ByteArrayOutputStream out = new ByteArrayOutputStream();
  74.         int offset = 0;
  75.         byte[] cache;
  76.         int i = 0;

  77.         while (inputLen - offset > 0) {
  78.             if (inputLen - offset > MAX_ENCRYPT_BLOCK) {
  79.                 cache = cipher.doFinal(data.getBytes(), offset, MAX_ENCRYPT_BLOCK);
  80.             } else {
  81.                 cache = cipher.doFinal(data.getBytes(), offset, inputLen - offset);
  82.             }
  83.             out.write(cache, 0, cache.length);
  84.             i++;
  85.             offset = i * MAX_ENCRYPT_BLOCK;
  86.         }
  87.         byte[] encryptedData = out.toByteArray();
  88.         out.close();

  89.         return new String(Base64.encodeBase64String(encryptedData));
  90.     }

  91.     public static String decrypt(String data, PrivateKey privateKey) throws Exception {
  92.         Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
  93.         cipher.init(Cipher.DECRYPT_MODE, privateKey);
  94.         byte[] dataBytes = Base64.decodeBase64(data);
  95.         int inputLen = dataBytes.length;
  96.         ByteArrayOutputStream out = new ByteArrayOutputStream();
  97.         int offset = 0;
  98.         byte[] cache;
  99.         int i = 0;

  100.         while (inputLen - offset > 0) {
  101.             if (inputLen - offset > MAX_DECRYPT_BLOCK) {
  102.                 cache = cipher.doFinal(dataBytes, offset, MAX_DECRYPT_BLOCK);
  103.             } else {
  104.                 cache = cipher.doFinal(dataBytes, offset, inputLen - offset);
  105.             }
  106.             out.write(cache, 0, cache.length);
  107.             i++;
  108.             offset = i * MAX_DECRYPT_BLOCK;
  109.         }
  110.         byte[] decryptedData = out.toByteArray();
  111.         out.close();

  112.         return new String(decryptedData, "UTF-8");
  113.     }


  114.     public static String sign(String data, PrivateKey privateKey) throws Exception {
  115.         byte[] keyBytes = privateKey.getEncoded();
  116.         PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
  117.         KeyFactory keyFactory = KeyFactory.getInstance(Encryption);
  118.         PrivateKey key = keyFactory.generatePrivate(keySpec);
  119.         Signature signature = Signature.getInstance(Privatesignature);
  120.         signature.initSign(key);
  121.         signature.update(data.getBytes());
  122.         return new String(Base64.decodeBase64(signature.sign()));
  123.     }


  124.     public static boolean verify(String srcData, PublicKey publicKey, String sign) throws Exception {
  125.         byte[] keyBytes = publicKey.getEncoded();
  126.         X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
  127.         KeyFactory keyFactory = KeyFactory.getInstance(Encryption);
  128.         PublicKey key = keyFactory.generatePublic(keySpec);
  129.         Signature signature = Signature.getInstance(Privatesignature);
  130.         signature.initVerify(key);
  131.         signature.update(srcData.getBytes());
  132.         return signature.verify(Base64.decodeBase64(sign.getBytes()));
  133.     }
  134. }

复制代码
回复

使用道具 举报

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

本版积分规则

教学服务系统

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

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

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