现在的位置: 首页 > 综合 > 正文

JAVA写加密算法(FFS)

2017年08月19日 ⁄ 综合 ⁄ 共 5325字 ⁄ 字号 评论关闭

1、生出大素数的方法,网上有很多

SecureRandom rod--new SecureRandom();//生成随机 序列 Biglnteger p=new BigInteger(m,200,md);//生成P BigInteger q=new Biglnteger(m,200,md);//生成q

一般为以上方法,但是若需要产生指定位数的素数,则需要考虑一番,经查找到一种方法,引自http://bbs.csdn.net/topics/110075333

PrimeNumberTest.java
==============================================
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class PrimeNumberTest {
    /** Creates a new instance of PrimeNumberTest */
    public PrimeNumberTest() {
    }
    public static void main(String[] args){
        //获得一个4位数的随机大素数
       long longVar4 = createRadomPrimeNunber(4);
       System.out.println(longVar4);
       //获得一个5位数的随机大素数
       long longVar5 = createRadomPrimeNunber(5);
       System.out.println(longVar5);
    }
    
    
    public static long createRadomPrimeNunber(int n){
        long recLong = 0;
        List list = listAllPrimeNumber(n);
        Random rd = new Random();
        int randomIndex = Math.abs( rd.nextInt()%list.size());
        recLong = ((Long)list.get(randomIndex)).longValue();
        return recLong;
       
    }
    public static List listAllPrimeNumber(int n){
        List list = new ArrayList();
        long low = (long)Math.pow(10,n-1);
        long high = (long)Math.pow(10,n) - 1;
        for(long i= low;i < high;i++){
            if( isSushu(i)) {
                list.add(new Long(i));
            }
        }
        return list;
    }
    public static boolean isSushu(long x){//定义一个判断一个数是否是素数的函数
        if(x<2) return false;
        if( x==2)return true;
        for(long i=2;i<= (long)Math.sqrt(x);i++)
            if(x%i==0) return false;
        return true;
    }
}

原理为:

将一下实现的原理给lz知道
首先,根据题目的意思,必须是素数,所以必须有一个函数判断一个数是不是素数

然后,要指定位数的,怎么办呢,我们可以先将指定位数的数中的所有的素数都找出来,放到一个
数组list里,这样问题就变成了,从list里随机取一个数出来了

如指定5位数,则从10000-99999中,找出所有的素数,放到一个数组list里去(测试结果是8363个素数,也就是说list.size() = 8363)

接着我们处理最后一个问题,生成一个 0 - 8363之间的随机数作为索引,根据此索引将list里的这个数取出来,就顺利将题目的要求实现了.


不过此方法的效率真心的慢啊!!

2、后来小组成员竟然说有直接生出指定位数的素数的方法,我了个去,为了这个花了我两个小时,有木有啊,各种挫败,为毛我查的时候没有而且会查到上面的东西!真心伤不起,而且是被别人严重鄙视,算了,鄙视就鄙视吧,把方法记下,留待后用,集中精力做事情。

一个完整的Java生出RSA的例子,摘自:http://dlutwy.blog.sohu.com/90667836.html


package
com.wangyou.cypher;


import java.math.BigInteger;
import java.security.SecureRandom;
import java.util.Hashtable;
import java.io.*;

public class RSA {
    
    private final static SecureRandom random = new SecureRandom();
    private BigInteger a;
    private BigInteger b;
    private BigInteger n;
    private BigInteger p;
    private BigInteger q;
    private Hashtable<String, BigInteger> publicKey;
    private Hashtable<String, BigInteger> privateKey;

    /**
     * 获取密钥
     * @return 密钥
     */
    public Hashtable<String, BigInteger> getPrivateKey() {
        return privateKey;
    }

    /**
     * 设置密钥
     * @param privateKey 密钥
     */
    public void setPrivateKey(Hashtable<String, BigInteger> privateKey) {
        this.privateKey = privateKey;
        p = privateKey.get("p");
        q = privateKey.get("q");
        a = privateKey.get("a");
        n = p.multiply(q);
    }

    /**
     * 获取公钥
     * @return 公钥
     */
    public Hashtable<String, BigInteger> getPublicKey() {
        return publicKey;
    }

    /**
     * 设置公钥
     * @param publicKey 公钥
     */
    public void setPublicKey(Hashtable<String, BigInteger> publicKey) {
        this.publicKey = publicKey;
        n = publicKey.get("n");
        b = publicKey.get("b");
    }
    /**
     * 产生长度为N位的公钥和私钥
     * @param N
     */
    public void genKey(int N)
    {
        // 产生两个N/2位的大素数p和q
        p = BigInteger.probablePrime(N/2, random);
        q = BigInteger.probablePrime(N/2, random);
        // 计算(p-1)*(q-1)
        BigInteger phi = (p.subtract(BigInteger.ONE)).multiply(q.subtract(BigInteger.ONE));
        // 计算模数p*q
        n = p.multiply(q);
        // 随便找一个b,使得gcd(b, phi) =1;
        // 通用的公钥是2^16 + 1=65537
        b = new BigInteger("65537");
        // 计算出a,即b的模n逆
        a = b.modInverse(phi);
        publicKey = new Hashtable<String, BigInteger>();
        privateKey = new Hashtable<String, BigInteger>();
        publicKey.put("n", n);
        publicKey.put("b", b);
        privateKey.put("p", p);
        privateKey.put("q", q);
        privateKey.put("a", a);
    }
    /**
     * 加密函数
     * @param plainText 明文
     * @return 密文
     */
    public byte[] encrypt(byte[] plainText) {
        return new BigInteger(plainText).modPow(b, n).toByteArray();
    }
    /**
     * 解密函数
     * @param cipherText 密文
     * @return 明文
     */
    public byte[] decrypt(byte[] cipherText) {
        return new BigInteger(cipherText).modPow(a, n).toByteArray();
    }
    
    public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException
    {
        RSA rsa = new RSA();
        rsa.genKey(1024); // 产生密钥
        // 保存私钥到文件 key
        ObjectOutputStream keyout = new ObjectOutputStream(new FileOutputStream("key"));
        keyout.writeObject(rsa.getPrivateKey());
        keyout.flush();
        keyout.close();
        // 加密一句消息
        byte[] cipher = rsa.encrypt("s你是最棒的".getBytes("gbk"));
        // 将加密消息写入文件
        ObjectOutputStream fileout = new ObjectOutputStream(new FileOutputStream("file"));
        fileout.writeObject(cipher);
        fileout.flush();
        // 读入密钥
        ObjectInputStream keyin = new ObjectInputStream(new FileInputStream("key"));
        RSA rsa1 = new RSA();
        Hashtable<String, BigInteger> privateKey = (Hashtable<String, BigInteger>)keyin.readObject();
        rsa1.setPrivateKey(privateKey);
        keyin.close();
        ObjectInputStream filein = new ObjectInputStream(new FileInputStream("file"));
        byte[] cp = (byte[])filein.readObject();
        // 解密
        byte[] plain = rsa1.decrypt(cp);
        System.out.println(new String(plain,"gbk"));
    }
}


抱歉!评论已关闭.