import org.jetbrains.annotations.NotNull;

import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.Random;

public class Painkiller {
    public BigInteger P,Q;
    public BigInteger N;
    public BigInteger NSQ;
    public BigInteger lamda;
    public int bitLength;
    public BigInteger g;
    public BigInteger u;
    public Painkiller(){
        Key(64,64);
    }
    public Painkiller(int bitLength,int certainty){
        Key(bitLength,certainty);
    }
    public Painkiller(BigInteger N,BigInteger lamda,int bitLength,BigInteger u){
        this.N=N;
        this.lamda=lamda;
        this.bitLength=bitLength;
        this.u=u;
    }
    public void Key(int bitLengthVal, int certainty) {
        bitLength = bitLengthVal;
        this.P = new BigInteger(bitLength / 2, certainty, new Random());
        this.Q = new BigInteger(bitLength / 2, certainty, new Random());
        this.N = P.multiply(Q);
        this.NSQ = N.multiply(N);
        this.g = N.add(new BigInteger("1"));
        this.lamda = P.subtract(BigInteger.ONE).multiply(Q.subtract(BigInteger.ONE))
                .divide(P.subtract(BigInteger.ONE).gcd(Q.subtract(BigInteger.ONE)));
        this.u = g.modPow(this.lamda, this.NSQ).subtract(BigInteger.ONE).divide(this.N).modInverse(this.N);
        if (this.g.modPow(this.lamda, this.NSQ).subtract(BigInteger.ONE).divide(this.N).gcd(this.N).intValue() != 1) {
            System.out.println("g的选取不合适!");
            System.exit(1);
        }
    }
    public BigInteger En(BigInteger m, @NotNull BigInteger r) {
        return g.modPow(m, this.NSQ).multiply(r.modPow(this.N, this.NSQ)).mod(this.NSQ);
    }
    public BigInteger En(BigInteger m) {
        BigInteger r = new BigInteger(bitLength, new Random());
//        System.out.println("random:"+r);
//        System.out.println(("g.modPow(m,NSQ:")+g.modPow(m,this.NSQ));
//        System.out.println("g.modPow(m,NSQ).mul(r.modPow(N,NSQ)):"+g.modPow(m,this.NSQ).multiply(r.modPow(this.N,this.NSQ)));
        return g.modPow(m, this.NSQ).multiply(r.modPow(this.N, this.NSQ)).mod(this.NSQ);
    }
    public BigInteger De(@NotNull BigInteger c) {
        return c.modPow(this.lamda, this.NSQ).subtract(BigInteger.ONE).divide(this.N).multiply(this.u).mod(this.N);
    }
    public BigInteger En(@NotNull String message){
        String encoded = Base64.getEncoder().encodeToString(message.getBytes());
        byte []encoded_b = encoded.getBytes(StandardCharsets.UTF_8);
        StringBuilder message_b = new StringBuilder();
        for(byte val:encoded_b){
//            System.out.printf("%03d",val);
            message_b.append(String.format("%03d", val));
        }
        return this.En(new BigInteger(String.valueOf(message_b)));
    }
    public String DeIfEnByString(BigInteger c){
        c = De(c);
        BigInteger md = new BigInteger("1000");
        System.out.println(c.toString().length());
        byte []bigIntToByteArr = new byte[(c.toString().length()/3+(c.toString().length()%3==0?0:1))];
        System.out.println(bigIntToByteArr.length);
        for(int i=0;i<bigIntToByteArr.length;i++){
            BigInteger val=c.mod(md);
            bigIntToByteArr[bigIntToByteArr.length-1-i]=Byte.parseByte(String.valueOf(val));
            c = c.divide(md);
        }
//        System.out.println("DeIfEnByString:"+ Arrays.toString(bigIntToByteArr));
//        System.out.println(new String(Base64.getDecoder().decode(new String(bigIntToByteArr))));
//        return new String("");
        return new String(Base64.getDecoder().decode(new String(bigIntToByteArr)));
    }
    public void showKeys(){
        System.out.println("bitLength:"+this.bitLength);
        System.out.println("Public Key:\nN:"+this.N+"\ng:"+this.g);
        System.out.println("Private Key:\nlamda:"+this.lamda+"\nu:"+this.u);
    }

    public static void main(String[] args) {
        Painkiller pkr = new Painkiller(64,32);
        pkr.showKeys();
        BigInteger crypto = pkr.En(new BigInteger("114514"));
        BigInteger message = pkr.De(crypto);
        System.out.println("crypto:"+crypto);
        System.out.println("message:"+message);
//        System.out.println(pkr.De(pkr.En(new BigInteger("11").add(new BigInteger("2"))).mod(pkr.NSQ)));



//        System.out.println(new BigInteger("123456789109876654321").modPow(new BigInteger("114514415411"),new BigInteger("123456789112409876654321")));
    }
}


//        Painkiller pkr = new Painkiller();
//        pkr.P=new BigInteger("1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890")

//        Painkiller pkr = new Painkiller(128,32);
//        BigInteger message = new BigInteger("12345678901234567890123456789012");
//        System.out.println(message);
//        System.out.println(pkr.En(message));
//        System.out.println(pkr.De(pkr.En(message)));


//    BigInteger bn = pkr.De(pkr.En(str));
//        System.out.println("bn"+bn);
//                BigInteger md = new BigInteger("1000");
//                byte []bigIntToByteArr = new byte[(bn.toString().length()/3+(bn.toString().length()%3==0?0:1))];
//                for(int i=0;i<bigIntToByteArr.length;i++){
//        BigInteger val=bn.mod(md);
//        System.out.print(val+" ");
//        bigIntToByteArr[bigIntToByteArr.length-1-i]=Byte.parseByte(String.valueOf(val));
//        bn = bn.divide(md);
//        }
//        System.out.println();
//        System.out.println(Arrays.toString(bigIntToByteArr));
//        for(byte key:bigIntToByteArr){
//        System.out.printf("%s",String.valueOf((char)key));
//        }
//        System.out.println();
//        System.out.println(new String(bigIntToByteArr));
//        byte[] decoded = Base64.getDecoder().decode(encoded);
//        System.out.println("Base64解码:"+new String(decoded));
//        System.out.println(new String(Base64.getDecoder().decode(new String(bigIntToByteArr))));



//        String encoded = Base64.getEncoder().encodeToString(str.getBytes());
//        System.out.println("Base64编码:"+encoded);
//        System.out.println(pkr.En(str));
//        System.out.println(pkr.En(str));
//        System.out.println(Arrays.toString(encoded.getBytes(StandardCharsets.UTF_8)));
//        byte []encoded_b = encoded.getBytes(StandardCharsets.UTF_8);
//        System.out.println(pkr.De(pkr.En(str)));
//        System.out.println(Arrays.toString(encoded_b));
//        pkr.DeIfEnByString(pkr.En(str));

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐