教学服务系统

 找回密码
 立即注册
搜索
查看: 739|回复: 4

信息计算2019级2班5号张欢

[复制链接]

8

主题

23

帖子

108

积分

注册会员

Rank: 2

积分
108
发表于 2022-5-27 17:27:01 | 显示全部楼层 |阅读模式
本帖最后由 张欢 于 2022-5-27 17:39 编辑

RSA加密及签名的实现
一、RSA加密及签名原理(来自网上)
RSA加密算法 RSA公钥加密体制包含如下3个算法:KeyGen(密钥生成算法),Encrypt(加密算法)以及Decrypt(解密算法)。
  • 。密钥生成算法以安全常数作为输入,输出一个公钥PK,和一个私钥SK。安全常数用于确定这个加密算法的安全性有多高,一般以加密算法使用的质数p的大小有关。越大,质数p一般越大,保证体制有更高的安全性。在RSA中,密钥生成算法如下:算法首先随机产生两个不同大质数p和q,计算N=pq。随后,算法计算欧拉函数。接下来,算法随机选择一个小于的整数e,并计算e关于的模反元素d。最后,公钥为PK=(N, e),私钥为SK=(N, d)。
  • 。加密算法以公钥PK和待加密的消息M作为输入,输出密文CT。在RSA中,加密算法如下:算法直接输出密文为
  • 。解密算法以私钥SK和密文CT作为输入,输出消息M。在RSA中,解密算法如下:算法直接输出明文为。由于e和d在下互逆,因此我们有:
所以,从算法描述中我们也可以看出:公钥用于对数据进行加密,私钥用于对数据进行解密。当然了,这个也可以很直观的理解:公钥就是公开的密钥,其公开了大家才能用它来加密数据。私钥是私有的密钥,谁有这个密钥才能够解密密文。否则大家都能看到私钥,就都能解密,那不就乱套了。

RSA签名算法 签名算法同样包含3个算法:KeyGen(密钥生成算法),Sign(签名算法),Verify(验证算法)。
  • 。密钥生成算法同样以安全常数作为输入,输出一个公钥PK和一个私钥SK。在RSA签名中,密钥生成算法与加密算法完全相同。
  • 。签名算法以私钥SK和待签名的消息M作为输入,输出签名。在RSA签名中,签名算法直接输出签名为。注意,签名算法和RSA加密体制中的解密算法非常像。
  • 。验证算法以公钥PK,签名以及消息M作为输入,输出一个比特值b。b=1意味着验证通过。b=0意味着验证不通过。在RSA签名中,验证算法首先计算,随后对比M'与M,如果相等,则输出b=1,否则输出b=0。注意:验证算法和RSA加密体制中的加密算法非常像。
所以,在签名算法中,私钥用于对数据进行签名,公钥用于对签名进行验证。这也可以直观地进行理解:对一个文件签名,当然要用私钥,因为我们希望只有自己才能完成签字。验证过程当然希望所有人都能够执行,大家看到签名都能通过验证证明确实是我自己签的


二、运行结果

本帖子中包含更多资源

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

x
回复

使用道具 举报

8

主题

23

帖子

108

积分

注册会员

Rank: 2

积分
108
 楼主| 发表于 2022-5-27 17:37:46 | 显示全部楼层
本帖最后由 张欢 于 2022-5-27 17:38 编辑

三、运行代码
  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. }
复制代码
回复

使用道具 举报

8

主题

23

帖子

108

积分

注册会员

Rank: 2

积分
108
 楼主| 发表于 2022-5-27 19:13:13 | 显示全部楼层
本帖最后由 张欢 于 2022-5-27 19:16 编辑

ECC椭圆曲线上公钥密码
一、ECC算法原理
ECC 是 Elliptic Curves Cryptography 的缩写,意为椭圆曲线密码编码学。和RSA算法一样,ECC算法也属于公开密钥算法。最初由 Koblitz 和 Miller 两人于1985年提出,其数学基础是利用椭圆曲线上的有理点构成Abel加法群上椭圆离散对数的计算困难性。

二、ECC 算法工作原理
ECC 算法加密过程
  • A选定一条椭圆曲线Ep(a,b),并取曲线上一点作为基点G
  • A选择一个私钥k,并生成公钥K=kG
  • A将Ep(a,b)和k,G发送给B
  • B收到后将明文编码到Ep(a,b)上一点M,并产生一个随机数r
  • B计算点C1=M+rK,C2=rG
  • B将C1,C2传给A
  • A计算C1-kC2=M+rkG-krG=M
  • A对M解码得到明文
攻击者只能得到Ep(a,b),G,K,C1,C2,没有k就无法得到M。
ECC 算法签名验签流程
  • A选定一条椭圆曲线Ep(a,b),并取曲线上一点作为基点G
  • A选择一个私钥k,并生成公钥K=kG
  • A产生一个随机数r,计算R(x,y)=rG
  • A计算Hash=SHA(M),M‘=M(modp)
  • A计算S=(Hash+M’k)/r(modp)
  • B获得S和M’,Ep(a,b),K,R(x,y)
  • B计算Hash=SHA(M),M’=M(modp)
  • B计算R’=(Hash*G+M’K)/S=(HashG+M’*kG)*r/(Hash+M’k)=rG=R(x,y),若R’=R,则验签成功。
回复

使用道具 举报

8

主题

23

帖子

108

积分

注册会员

Rank: 2

积分
108
 楼主| 发表于 2022-5-27 19:16:37 | 显示全部楼层
本帖最后由 张欢 于 2022-5-27 19:36 编辑

三、代码实现
EccUtil.java
  1. package ecc1;

  2. import java.math.BigInteger;
  3. import java.util.Random;

  4. public class EccUtil {
  5.     static E e;// 椭圆曲线
  6.     Pare pare;// 椭圆上的已知点
  7.     long privatekey;// 7位速度变慢 私钥--随机
  8.     Pare publickey;// 公钥

  9.     public EccUtil() {
  10.         super();
  11.         Random rand = new Random();
  12.         e = new E(BigInteger.probablePrime(30, rand).intValue(), rand.nextInt(1024), rand.nextInt(1024));
  13.         this.privatekey = rand.nextInt(1024);// 7位速度变慢 私钥--随机
  14.         this.pare = new Pare(rand.nextInt(10000000), rand.nextInt(10000000));
  15.         this.publickey = this.pare.multiply(privatekey);// new Pare();
  16.     }

  17.     class E {// 表示椭圆曲线方程
  18.         Long p;// 模p的椭圆群
  19.         Long a;
  20.         Long b;

  21.         public E(long p, long a, long b) {
  22.             super();
  23.             this.p = p;
  24.             this.a = a;
  25.             this.b = b;
  26.         }

  27.     }

  28.     class Message {// 传送消息的最小单元
  29.         Pare pa;
  30.         Pare pb;

  31.         public Message(Pare pa, Pare pb) {
  32.             super();
  33.             this.pa = pa;
  34.             this.pb = pb;
  35.         }

  36.         @Override
  37.         public String toString() {
  38.             return this.pa.toString() + " " + this.pb.toString();
  39.         }
  40.     }

  41.     class Pare {// 椭圆曲线上的点(x,y)
  42.         long x;
  43.         long y;

  44.         public Pare() {
  45.             super();
  46.         }

  47.         public Pare(long x, long y) {
  48.             super();

  49.             this.x = x;
  50.             this.y = y;
  51.         }

  52.         // 加法
  53.         public Pare add(Pare pare) {
  54.             if (this.x == Integer.MAX_VALUE) {// 为无穷大时O+P=P
  55.                 return pare;
  56.             }
  57.             Pare res = new Pare();
  58.             if (this.y == pare.y && this.x == pare.x) {// 相等时
  59.                 long d = moddivision(3 * this.x * this.x + EccUtil.e.a, EccUtil.e.p, 2 * this.y);

  60.                 res.x = d * d - 2 * this.x;
  61.                 res.x = mod(res.x, EccUtil.e.p);

  62.                 res.y = d * (this.x - res.x) - this.y;
  63.                 res.y = mod(res.y, EccUtil.e.p);
  64.             } else if (pare.x - this.x != 0) {
  65.                 long d = moddivision(pare.y - this.y, EccUtil.e.p, pare.x - this.x);
  66.                 res.x = d * d - this.x - pare.x;
  67.                 res.x = mod(res.x, EccUtil.e.p);

  68.                 res.y = d * (this.x - res.x) - this.y;
  69.                 res.y = mod(res.y, EccUtil.e.p);
  70.             } else {// P Q互逆,返回无穷大
  71.                 res.x = Integer.MAX_VALUE;
  72.                 res.y = Integer.MAX_VALUE;
  73.             }

  74.             return res;
  75.         }

  76.         // 减法
  77.         public Pare less(Pare p) {
  78.             p.y *= -1;
  79.             return add(p);
  80.         }

  81.         // 乘法
  82.         public Pare multiply(long num) {
  83.             Pare p = new Pare(this.x, this.y);
  84.             for (long i = 1; i < num; i++) {
  85.                 p = p.add(this);
  86.             }
  87.             return p;
  88.         }

  89.         // 求余,解决负号问题
  90.         public long mod(long a, long b) {
  91.             a = a % b;
  92.             while (a < 0) {
  93.                 a += b;
  94.             }
  95.             return a;
  96.         }

  97.         public long moddivision(long a, long b, long c) {
  98.             a = mod(a, b);
  99.             c = mod(c, b);
  100.             a = a * EccMath.exgcd(c, b);
  101.             return mod(a, b);
  102.         }

  103.         @Override
  104.         public String toString() {
  105.             return EccTools.obox(EccTools.long2hexStr(this.x), 4) + " "
  106.                     + EccTools.obox(EccTools.long2hexStr(this.y), 4);
  107.         }
  108.     }

  109.     // 加密
  110.     public Message encryption(Pare g, Pare pbk, Pare word) {
  111.         pbk = g.multiply(privatekey);// 公钥
  112.         int d = new Random().nextInt(1024);// 随机数
  113.         Pare dg = g.multiply(d);
  114.         Pare dp = pbk.multiply(d);
  115.         Pare send = word.add(dp);
  116.         return new Message(dg, send);
  117.     }

  118.     public String encryption(Pare g, Pare pbk, String word) {
  119.         StringBuffer sb = new StringBuffer();
  120.         Pare[] words = Str2Pares(word);
  121.         for (int i = 0; i < words.length; i++) {
  122.             sb.append(encryption(g, pbk, words[i]).toString());
  123.             sb.append(" ");
  124.         }
  125.         return sb.toString();
  126.     }

  127.     public String encryption(String word) {
  128.         StringBuffer sb = new StringBuffer();
  129.         Pare[] words = Str2Pares(word);
  130.         for (int i = 0; i < words.length; i++) {
  131.             sb.append(encryption(this.pare, this.publickey, words[i]).toString());
  132.             sb.append(" ");
  133.         }
  134.         return sb.toString();
  135.     }

  136.     // 解密
  137.     public Pare decryption(Message m) {
  138.         Pare pab = m.pa.multiply(this.privatekey);
  139.         Pare result = m.pb.less(pab);
  140.         return result;
  141.     }

  142.     public String decryption(String s) {
  143.         StringBuffer sb = new StringBuffer();
  144.         Message[] mes = hexStr2Messages(s);
  145.         for (int i = 0; i < mes.length; i++) {
  146.             sb.append(decryption(mes[i]).toString());
  147.         }
  148.         return EccTools.hexStr2Str(sb.toString().replace(" ", ""));
  149.     }

  150.     public static void print(Object o) {
  151.         System.out.println(o);
  152.     }

  153.     // 将字符串转换为 值对
  154.     public Pare[] Str2Pares(String string) {

  155.         Pare[] pares;
  156.         if (string.length() % 2 != 0) {
  157.             pares = new Pare[string.length() / 2 + 1];
  158.         } else {
  159.             pares = new Pare[string.length() / 2];
  160.         }
  161.         char[] chars = string.toCharArray();
  162.         int i = 0;
  163.         for (i = 0; i < string.length() / 2; i++) {
  164.             pares[i] = new Pare(chars[i * 2], chars[i * 2 + 1]);
  165.         }
  166.         if (string.length() % 2 != 0) {
  167.             pares[i] = new Pare(chars[i * 2], 0);
  168.         }
  169.         return pares;
  170.     }

  171.     // 将值对转换成16进制字符串
  172.     public String Pares2hexStr(Pare[] pares) {
  173.         StringBuffer s = new StringBuffer();
  174.         for (int i = 0; i < pares.length; i++) {
  175.             s.append(pares[i].toString());
  176.         }
  177.         return s.toString();
  178.     }

  179.     // 将16进制字符串转为 消息串
  180.     public Message[] hexStr2Messages(String s) {
  181.         String[] ss = s.split(" ");
  182.         Message[] mes = new Message[ss.length / 4];
  183.         for (int i = 0; i < mes.length; i++) {
  184.             long pax = EccTools.hexStr2long(ss[i * 4]);
  185.             long pay = EccTools.hexStr2long(ss[i * 4 + 1]);
  186.             long pbx = EccTools.hexStr2long(ss[i * 4 + 2]);
  187.             long pby = EccTools.hexStr2long(ss[i * 4 + 3]);
  188.             mes[i] = new Message(new Pare(pax, pay), new Pare(pbx, pby));
  189.         }
  190.         return mes;
  191.     }

  192.     // 将消息串转为16进制字符串
  193.     public String Messages2hexStr(Message[] mes) {
  194.         StringBuffer sb = new StringBuffer();
  195.         for (int i = 0; i < mes.length; i++) {
  196.             sb.append(mes[i].toString());
  197.             sb.append(" ");
  198.         }
  199.         return sb.toString();
  200.     }

  201.     public static void main(String[] args) {
  202.         EccUtil ecc = new EccUtil();
  203.         print("私钥:" + ecc.privatekey);
  204.         print("公钥:" + ecc.publickey);
  205.         print("基点:" + ecc.pare);
  206.         print("");
  207.         String s = "智者不入爱河,寡王一路硕博";

  208.         String jm = ecc.encryption(s);
  209.         print("密文:   " + jm);
  210.         String mw = ecc.decryption(jm);
  211.         print("明文:   " + mw);

  212.     }
  213. }
复制代码
回复

使用道具 举报

8

主题

23

帖子

108

积分

注册会员

Rank: 2

积分
108
 楼主| 发表于 2022-5-27 19:19:42 | 显示全部楼层
本帖最后由 张欢 于 2022-5-27 19:37 编辑

续:
EccMath.java
  1. package ecc1;

  2. import java.math.BigInteger;

  3. public class EccMath {
  4.     // 此方法求余数。prime:素数,primitive:本原元,random:随机数。
  5.     public static long reaminder(long prime, long primitive, long random) {
  6.         long reamin = primitive % prime;
  7.         long currentreamin = reamin;
  8.         String binary = Long.toBinaryString(random);
  9.         System.out.println(binary);
  10.         for (int i = 0; i < binary.length() - 1; i++) {
  11.             if (binary.charAt(i + 1) == '0') {
  12.                 currentreamin = (currentreamin * currentreamin) % prime;
  13.             } else {
  14.                 currentreamin = (currentreamin * currentreamin * reamin) % prime;
  15.             }

  16.         }

  17.         return currentreamin;
  18.     }

  19.     public static BigInteger reaminder(BigInteger prime, BigInteger primitive, long random) {
  20.         BigInteger reamin = primitive.mod(prime);
  21.         BigInteger currentreamin = reamin;
  22.         String binary = Long.toBinaryString(random);
  23.         for (int i = 0; i < binary.length() - 1; i++) {
  24.             if (binary.charAt(i + 1) == '0') {
  25.                 currentreamin = currentreamin.multiply(currentreamin).mod(prime);
  26.             } else {
  27.                 currentreamin = currentreamin.multiply(currentreamin).multiply(reamin).mod(prime);
  28.             }

  29.         }
  30.         return currentreamin;
  31.     }

  32.     public static BigInteger reaminder(String prim, String primitiv, String rand) {
  33.         BigInteger prime = new BigInteger(prim);
  34.         BigInteger primitive = new BigInteger(primitiv);
  35.         Long random = new Long(rand);
  36.         BigInteger reamin = primitive.mod(prime);
  37.         BigInteger currentreamin = reamin;
  38.         String binary = Long.toBinaryString(random);
  39.         for (int i = 0; i < binary.length() - 1; i++) {
  40.             if (binary.charAt(i + 1) == '0') {
  41.                 currentreamin = currentreamin.multiply(currentreamin).mod(prime);
  42.             } else {
  43.                 currentreamin = currentreamin.multiply(currentreamin).multiply(reamin).mod(prime);
  44.             }

  45.         }
  46.         return currentreamin;
  47.     }

  48.     // 此方法判断素数
  49.     public static boolean isPrime(long num) {
  50.         boolean flag = true;
  51.         for (long i = 2; i < num / 2; i++) {
  52.             if (num == 2) {
  53.                 break;
  54.             }
  55.             if (num % i == 0) {
  56.                 flag = false;
  57.                 break;
  58.             }
  59.         }
  60.         return flag;
  61.     }

  62.     // 求最大公约数:欧几里得算法,辗转相除法
  63.     public static long gcd(long a, long b) {
  64.         long reamin = a % b;
  65.         if (reamin == 0) {
  66.             return b;
  67.         } else {
  68.             return gcd(b, reamin);
  69.         }
  70.     }

  71.     // 扩展的欧几里得算法求逆元,如果有返回值,没有返回-1
  72.     public static long exgcd(long a, long b) {
  73.         long x1 = 1, x2 = 0, x3 = b, y1 = 0, y2 = 1, y3 = a;
  74.         while (true) {
  75.             if (y3 == 0) {
  76.                 return -1;
  77.             }
  78.             if (y3 == 1) {
  79.                 return y2 > 0 ? y2 : y2 + b;
  80.             }
  81.             long t1, t2, t3;
  82.             long q = x3 / y3;
  83.             t1 = x1 - q * y1;
  84.             t2 = x2 - q * y2;
  85.             t3 = x3 - q * y3;
  86.             x1 = y1;
  87.             x2 = y2;
  88.             x3 = y3;
  89.             y1 = t1;
  90.             y2 = t2;
  91.             y3 = t3;
  92.         }
  93.     }

  94.     public static BigInteger exgcd(BigInteger a, BigInteger b) {
  95.         BigInteger x1 = BigInteger.ONE, x2 = BigInteger.ZERO, x3 = b, y1 = BigInteger.ZERO, y2 = BigInteger.ONE, y3 = a;
  96.         while (true) {
  97.             if (y3.equals(BigInteger.ZERO)) {
  98.                 return BigInteger.ZERO.subtract(BigInteger.ONE);
  99.             }
  100.             if (y3.equals(BigInteger.ONE)) {
  101.                 return y2;
  102.             }
  103.             BigInteger t1, t2, t3;
  104.             BigInteger q = x3.divide(y3);// x3/y3;
  105.             t1 = x1.subtract(q.multiply(y1));// x1-q*y1;
  106.             t2 = x2.subtract(q.multiply(y2));// x2 - q*y2;
  107.             t3 = x3.subtract(q.multiply(y3));// x3 - q*y3;
  108.             x1 = y1;
  109.             x2 = y2;
  110.             x3 = y3;
  111.             y1 = t1;
  112.             y2 = t2;
  113.             y3 = t3;
  114.         }
  115.     }

  116. }

复制代码

EccTools.java

  1. package ecc1;

  2. public class EccTools {
  3.     // 字符串左边补0直到长度为i
  4.     public static String obox(String s, int i) {
  5.         String ss = s;
  6.         while (ss.length() < i) {
  7.             ss = "0" + ss;
  8.         }
  9.         return ss;
  10.     }

  11.     // 字符串右边补0直到长度为i
  12.     public static String boxo(String s, int i) {
  13.         String ss = s;
  14.         while (ss.length() < i) {
  15.             ss += "0";
  16.         }
  17.         return ss;
  18.     }

  19.     // 将字符串变成16进制字符串
  20.     public static String Str2hexStr(String s) {
  21.         StringBuffer sb = new StringBuffer();
  22.         for (int i = 0; i < s.length(); i++) {
  23.             sb.append(obox(Integer.toHexString(s.charAt(i)), 4));
  24.         }
  25.         return sb.toString();
  26.     }

  27.     // 将16进制字符串变成字符串
  28.     public static String hexStr2Str(String s) {
  29.         StringBuffer sb = new StringBuffer();
  30.         int index = 0;
  31.         int length = s.length();
  32.         while (index + 4 <= length) {
  33.             String sh = s.substring(index, index + 4);
  34.             sb.append((char) Integer.parseInt(sh, 16));
  35.             index += 4;
  36.         }
  37.         if (sb.charAt(sb.length() - 1) == 0) {
  38.             sb.deleteCharAt(sb.length() - 1);
  39.         }
  40.         return sb.toString();
  41.     }

  42.     // String数组转换为char数组
  43.     public static char[] Ss2Cs(String[] s) {
  44.         char[] result = new char[s.length];
  45.         for (int i = 0; i < s.length; i++) {
  46.             result[i] = (char) Integer.parseInt(s[i], 16);
  47.         }
  48.         return result;
  49.     }

  50.     // String转换为char数组
  51.     public static char[] Str2Cs(String s) {
  52.         char[] result = new char[s.length() / 2];
  53.         for (int i = 0; i < s.length() / 2; i++) {
  54.             StringBuffer sb = new StringBuffer();
  55.             sb.append(s.charAt(i * 2));
  56.             sb.append(s.charAt(i * 2 + 1));
  57.             result[i] = (char) Integer.parseInt(sb.toString(), 16);
  58.         }
  59.         return result;
  60.     }

  61.     // hexString转换为数组
  62.     public static char[] hexStr2Cs(String s) {

  63.         char[] result = new char[s.length() / 2];
  64.         for (int i = 0; i < s.length() / 2; i++) {
  65.             StringBuffer sb = new StringBuffer();
  66.             sb.append(s.charAt(i * 2));
  67.             sb.append(s.charAt(i * 2 + 1));
  68.             result[i] = (char) Integer.parseInt(sb.toString(), 16);
  69.         }
  70.         return result;
  71.     }

  72.     // char数组转换为String数组
  73.     public static String[] Cs2Ss(char[] s) {
  74.         String[] result = new String[s.length];
  75.         for (int i = 0; i < s.length; i++) {
  76.             result[i] = Integer.toHexString(s[i]);
  77.         }
  78.         return result;
  79.     }

  80.     // char数组转换为hexString
  81.     public static String Cs2hexStr(char[] s) {
  82.         StringBuffer sb = new StringBuffer();
  83.         for (int i = 0; i < s.length; i++) {
  84.             sb.append(obox(Integer.toHexString(s[i]), 2));
  85.         }
  86.         return sb.toString();
  87.     }

  88.     // long转换为hexString
  89.     public static String long2hexStr(long lo) {

  90.         return Long.toHexString(lo);
  91.     }

  92.     // longs数组转换为hexString
  93.     public static String longs2hexStr(long[] lo) {
  94.         StringBuffer sb = new StringBuffer();
  95.         for (int i = 0; i < lo.length; i++) {
  96.             sb.append(Long.toHexString(lo[0]));
  97.             sb.append(" ");
  98.         }
  99.         return sb.toString();
  100.     }

  101.     // hexString转换为long
  102.     public static long hexStr2long(String s) {
  103.         return Long.parseLong(s, 16);
  104.     }

  105.     // hexString转换为long数组
  106.     public static long[] hexStr2longs(String s) {
  107.         String[] ss = s.split(" ");
  108.         long[] ls = new long[ss.length];
  109.         for (int i = 0; i < ls.length; i++) {
  110.             ls[i] = Long.parseLong(ss[i], 16);
  111.         }
  112.         return ls;
  113.     }

  114. }

复制代码

四、运行结果

本帖子中包含更多资源

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

x
回复

使用道具 举报

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

本版积分规则

教学服务系统

GMT+8, 2025-4-30 07:46 , Processed in 0.017941 second(s), 19 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

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