mirror of
https://gitee.com/dromara/hutool.git
synced 2025-04-05 17:37:59 +08:00
添加 同态加密算法 Paillier
This commit is contained in:
parent
84621a71e8
commit
c3a05d5159
@ -2,13 +2,14 @@
|
||||
# 🚀Changelog
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
# 5.8.20(2023-06-06)
|
||||
# 5.8.20(2023-06-09)
|
||||
|
||||
### 🐣新特性
|
||||
* 【core 】 UrlQuery增加setStrict方法,区分是否严格模式(issue#I78PB1@Gitee)
|
||||
* 【poi 】 添加系列方法writeCol,以支持按列输出(pr#1003@Gitee)
|
||||
* 【core 】 CollUtil新增anyMatch和allMatch方法(pr#1008@Gitee)
|
||||
* 【core 】 CsvWriter如果开启了append=true,默认自动开启endingLineBreak=true(pr#1010@Gitee)
|
||||
* 【crypto】 CsvWriter如果开启了append=true,默认自动开启endingLineBreak=true(pr#1010@Gitee)
|
||||
|
||||
### 🐞Bug修复
|
||||
* 【core 】 修复TreeUtil.getParentsName()获取到的路径集合中存在值为null的路径名称问题(issue#I795IN@Gitee)
|
||||
|
@ -1,30 +0,0 @@
|
||||
package cn.hutool.crypto.asymmetric;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
/** 存放Paillier 公钥
|
||||
*
|
||||
* @author Revers.
|
||||
**/
|
||||
public class PaillierpublicKey{
|
||||
private BigInteger n;
|
||||
private BigInteger g;
|
||||
|
||||
public PaillierpublicKey(BigInteger n, BigInteger g) {
|
||||
if (n == null) {
|
||||
throw new NullPointerException("n is null");
|
||||
}
|
||||
if (g == null) {
|
||||
throw new NullPointerException("g is null");
|
||||
}
|
||||
this.n = n;
|
||||
this.g = g;
|
||||
}
|
||||
|
||||
public BigInteger getN() {
|
||||
return n;
|
||||
}
|
||||
public BigInteger getG() {
|
||||
return g;
|
||||
}
|
||||
}
|
@ -1,4 +1,16 @@
|
||||
package cn.hutool.crypto.asymmetric;
|
||||
/*
|
||||
* Copyright (c) 2023 looly(loolly@aliyun.com)
|
||||
* Hutool is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
package cn.hutool.crypto.asymmetric.paillier;
|
||||
|
||||
import cn.hutool.core.util.HexUtil;
|
||||
|
||||
@ -8,16 +20,16 @@ import java.util.Random;
|
||||
|
||||
/**
|
||||
* 同态加密算法Paillier
|
||||
*
|
||||
* <p>
|
||||
* 加法同态,存在有效算法+,E(x+y)=E(x)+E(y)或者 x+y=D(E(x)+E(y))成立,并且不泄漏 x 和 y。
|
||||
* 乘法同态,存在有效算法*,E(x×y)=E(x)*E(y)或者 xy=D(E(x)*E(y))成立,并且不泄漏 x 和 y。
|
||||
*
|
||||
* <p>
|
||||
* 方案安全性可以归约到判定性合数剩余假设(Decisional Composite Residuosity Assumption, DCRA),即给定一个合数n和整数z,判定z是否在n^2下是否是n次剩余是困难的。
|
||||
* 这个假设经过了几十年的充分研究,到目前为止还没有多项式时间的算法可以攻破,所以Paillier加密方案的安全性被认为相当可靠。
|
||||
*
|
||||
* <p>
|
||||
* 字符串文本加解密相互配对,此时无法使用同态加法和同态乘法
|
||||
* 数值类型不可使用字符串加解密
|
||||
*
|
||||
* <p>
|
||||
* 公钥加密和同态加法/同态乘法运算
|
||||
* 私钥解密
|
||||
*
|
||||
@ -27,14 +39,14 @@ public class Paillier {
|
||||
|
||||
//公钥 n g
|
||||
//私钥 n lambda u
|
||||
private static int bitLength = 2048;
|
||||
private static int certainty = 256;
|
||||
private static final int bitLength = 2048;
|
||||
private static final int certainty = 256;
|
||||
|
||||
/**
|
||||
* 生成密钥算法。(默认)
|
||||
* @return PaillierKeyPair 公钥私钥对
|
||||
*/
|
||||
public static final PaillierKeyPair generateKey() {
|
||||
public static PaillierKeyPair generateKey() {
|
||||
return generateKey(bitLength,certainty);
|
||||
}
|
||||
|
||||
@ -45,19 +57,18 @@ public class Paillier {
|
||||
* @param certainty 此构造函数的执行时间与此参数的值成比例。
|
||||
* @return PaillierKeyPair 公钥私钥对
|
||||
*/
|
||||
public static final PaillierKeyPair generateKey(int bitLength,int certainty) {
|
||||
BigInteger p =new BigInteger(bitLength / 2, certainty, new SecureRandom());
|
||||
BigInteger q =new BigInteger(bitLength / 2, certainty, new SecureRandom());
|
||||
BigInteger n = p.multiply(q);
|
||||
BigInteger nSquare = n.multiply(n);
|
||||
BigInteger lambda = p.subtract(BigInteger.ONE).multiply(q.subtract(BigInteger.ONE))
|
||||
public static PaillierKeyPair generateKey(final int bitLength, final int certainty) {
|
||||
final BigInteger p =new BigInteger(bitLength / 2, certainty, new SecureRandom());
|
||||
final BigInteger q =new BigInteger(bitLength / 2, certainty, new SecureRandom());
|
||||
final BigInteger n = p.multiply(q);
|
||||
final BigInteger nSquare = n.multiply(n);
|
||||
final BigInteger lambda = p.subtract(BigInteger.ONE).multiply(q.subtract(BigInteger.ONE))
|
||||
.divide(p.subtract(BigInteger.ONE).gcd(q.subtract(BigInteger.ONE)));
|
||||
BigInteger g = n.add(BigInteger.ONE);
|
||||
BigInteger u = g.modPow(lambda, nSquare).subtract(BigInteger.ONE).divide(n).modInverse(n);
|
||||
PaillierpublicKey publicKey = new PaillierpublicKey(n,g);
|
||||
PaillierPrivateKey privateKey = new PaillierPrivateKey(n, lambda,u);
|
||||
PaillierKeyPair keyPair = new PaillierKeyPair(publicKey,privateKey);
|
||||
return keyPair;
|
||||
final BigInteger g = n.add(BigInteger.ONE);
|
||||
final BigInteger u = g.modPow(lambda, nSquare).subtract(BigInteger.ONE).divide(n).modInverse(n);
|
||||
final PaillierpublicKey publicKey = new PaillierpublicKey(n,g);
|
||||
final PaillierPrivateKey privateKey = new PaillierPrivateKey(n, lambda,u);
|
||||
return new PaillierKeyPair(publicKey,privateKey);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -69,10 +80,10 @@ public class Paillier {
|
||||
*
|
||||
* @return byte[]密文
|
||||
*/
|
||||
public static final byte[] encryptString(String text, PaillierpublicKey publicKey) {
|
||||
BigInteger r = new BigInteger(bitLength, new Random());
|
||||
BigInteger n = publicKey.getN();
|
||||
BigInteger nsquare = n.multiply(n);
|
||||
public static byte[] encryptString(final String text, final PaillierpublicKey publicKey) {
|
||||
final BigInteger r = new BigInteger(bitLength, new Random());
|
||||
final BigInteger n = publicKey.getN();
|
||||
final BigInteger nsquare = n.multiply(n);
|
||||
return publicKey.getG().modPow( new BigInteger(HexUtil.encodeHexStr(text),16), nsquare).multiply(r.modPow(n, nsquare)).mod(nsquare).toByteArray();
|
||||
}
|
||||
|
||||
@ -83,12 +94,12 @@ public class Paillier {
|
||||
* @param privateKey 私钥
|
||||
* @return 解密的明文
|
||||
*/
|
||||
public static final String decryptString(byte[] ciphertext, PaillierPrivateKey privateKey) {
|
||||
BigInteger n = privateKey.getN();
|
||||
BigInteger lambda = privateKey.getLambda();
|
||||
BigInteger u = privateKey.getu();
|
||||
BigInteger nsquare = n.multiply(n);
|
||||
String s = new BigInteger(ciphertext).modPow(lambda, nsquare).subtract(BigInteger.ONE).divide(n).multiply(u).mod(n).toString();
|
||||
public static String decryptString(final byte[] ciphertext, final PaillierPrivateKey privateKey) {
|
||||
final BigInteger n = privateKey.getN();
|
||||
final BigInteger lambda = privateKey.getLambda();
|
||||
final BigInteger u = privateKey.getu();
|
||||
final BigInteger nsquare = n.multiply(n);
|
||||
final String s = new BigInteger(ciphertext).modPow(lambda, nsquare).subtract(BigInteger.ONE).divide(n).multiply(u).mod(n).toString();
|
||||
return HexUtil.decodeHexStr(new BigInteger(s).toString(16));
|
||||
}
|
||||
|
||||
@ -99,10 +110,10 @@ public class Paillier {
|
||||
* @param publicKey 公钥
|
||||
* @return byte[]密文
|
||||
*/
|
||||
public static final byte[] encrypt(BigInteger text, PaillierpublicKey publicKey) {
|
||||
BigInteger r = new BigInteger(bitLength, new Random());
|
||||
BigInteger n = publicKey.getN();
|
||||
BigInteger nsquare = n.multiply(n);
|
||||
public static byte[] encrypt(final BigInteger text, final PaillierpublicKey publicKey) {
|
||||
final BigInteger r = new BigInteger(bitLength, new Random());
|
||||
final BigInteger n = publicKey.getN();
|
||||
final BigInteger nsquare = n.multiply(n);
|
||||
return publicKey.getG().modPow(text, nsquare).multiply(r.modPow(n, nsquare)).mod(nsquare).toByteArray();
|
||||
}
|
||||
|
||||
@ -113,11 +124,11 @@ public class Paillier {
|
||||
* @param privateKey 私钥
|
||||
* @return 解密的明文
|
||||
*/
|
||||
public static final String decrypt(byte[] ciphertext, PaillierPrivateKey privateKey) {
|
||||
BigInteger n = privateKey.getN();
|
||||
BigInteger lambda = privateKey.getLambda();
|
||||
BigInteger u = privateKey.getu();
|
||||
BigInteger nsquare = n.multiply(n);
|
||||
public static String decrypt(final byte[] ciphertext, final PaillierPrivateKey privateKey) {
|
||||
final BigInteger n = privateKey.getN();
|
||||
final BigInteger lambda = privateKey.getLambda();
|
||||
final BigInteger u = privateKey.getu();
|
||||
final BigInteger nsquare = n.multiply(n);
|
||||
return new BigInteger(ciphertext).modPow(lambda, nsquare).subtract(BigInteger.ONE).divide(n).multiply(u).mod(n).toString();
|
||||
}
|
||||
|
||||
@ -129,7 +140,7 @@ public class Paillier {
|
||||
* @param publicKey 公钥
|
||||
* @return byte[]密文
|
||||
*/
|
||||
public static final byte[] add(BigInteger ciphertext,BigInteger ciphertext2,PaillierpublicKey publicKey){
|
||||
public static byte[] add(final BigInteger ciphertext, final BigInteger ciphertext2, final PaillierpublicKey publicKey){
|
||||
return ciphertext.add(ciphertext2).multiply(publicKey.getN()).toByteArray();
|
||||
}
|
||||
|
||||
@ -141,7 +152,7 @@ public class Paillier {
|
||||
* @param publicKey 公钥
|
||||
* @return byte[]密文
|
||||
*/
|
||||
public static final byte[] add(String ciphertext,String ciphertext2,PaillierpublicKey publicKey){
|
||||
public static byte[] add(final String ciphertext, final String ciphertext2, final PaillierpublicKey publicKey){
|
||||
return new BigInteger(ciphertext).multiply(new BigInteger(ciphertext2)).mod(publicKey.getN().multiply(publicKey.getN())).toByteArray();
|
||||
}
|
||||
|
||||
@ -153,7 +164,7 @@ public class Paillier {
|
||||
* @param publicKey 公钥
|
||||
* @return byte[]密文
|
||||
*/
|
||||
public static final byte[] add(byte[] ciphertext,byte[] ciphertext2,PaillierpublicKey publicKey){
|
||||
public static byte[] add(final byte[] ciphertext, final byte[] ciphertext2, final PaillierpublicKey publicKey){
|
||||
return new BigInteger(ciphertext).multiply(new BigInteger(ciphertext2)).mod(publicKey.getN().multiply(publicKey.getN())).toByteArray();
|
||||
}
|
||||
|
||||
@ -165,7 +176,7 @@ public class Paillier {
|
||||
* @param publicKey 公钥
|
||||
* @return byte[]密文
|
||||
*/
|
||||
public static final byte[] multiply(BigInteger ciphertext,BigInteger number,PaillierpublicKey publicKey){
|
||||
public static byte[] multiply(final BigInteger ciphertext, final BigInteger number, final PaillierpublicKey publicKey){
|
||||
return ciphertext.modPow(number,publicKey.getN().multiply(publicKey.getN())).toByteArray();
|
||||
}
|
||||
|
||||
@ -177,7 +188,7 @@ public class Paillier {
|
||||
* @param publicKey 公钥
|
||||
* @return byte[]密文
|
||||
*/
|
||||
public static final byte[] multiply(String ciphertext,BigInteger number,PaillierpublicKey publicKey){
|
||||
public static byte[] multiply(final String ciphertext, final BigInteger number, final PaillierpublicKey publicKey){
|
||||
return new BigInteger(ciphertext).modPow(number,publicKey.getN().multiply(publicKey.getN())).toByteArray();
|
||||
}
|
||||
|
||||
@ -189,7 +200,7 @@ public class Paillier {
|
||||
* @param publicKey 公钥
|
||||
* @return byte[]密文
|
||||
*/
|
||||
public static final byte[] multiply(byte[] ciphertext,BigInteger number,PaillierpublicKey publicKey){
|
||||
public static byte[] multiply(final byte[] ciphertext, final BigInteger number, final PaillierpublicKey publicKey){
|
||||
return new BigInteger(ciphertext).modPow(number,publicKey.getN().multiply(publicKey.getN())).toByteArray();
|
||||
}
|
||||
}
|
@ -1,4 +1,16 @@
|
||||
package cn.hutool.crypto.asymmetric;
|
||||
/*
|
||||
* Copyright (c) 2023 looly(loolly@aliyun.com)
|
||||
* Hutool is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
package cn.hutool.crypto.asymmetric.paillier;
|
||||
|
||||
/**
|
||||
* 存放Paillier 公钥私钥对
|
@ -1,4 +1,16 @@
|
||||
package cn.hutool.crypto.asymmetric;
|
||||
/*
|
||||
* Copyright (c) 2023 looly(loolly@aliyun.com)
|
||||
* Hutool is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
package cn.hutool.crypto.asymmetric.paillier;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (c) 2023 looly(loolly@aliyun.com)
|
||||
* Hutool is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
package cn.hutool.crypto.asymmetric.paillier;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
/**
|
||||
* 存放Paillier 公钥
|
||||
*
|
||||
* @author Revers.
|
||||
*/
|
||||
public class PaillierpublicKey {
|
||||
private BigInteger n;
|
||||
private BigInteger g;
|
||||
|
||||
public PaillierpublicKey(BigInteger n, BigInteger g) {
|
||||
if (n == null) {
|
||||
throw new NullPointerException("n is null");
|
||||
}
|
||||
if (g == null) {
|
||||
throw new NullPointerException("g is null");
|
||||
}
|
||||
this.n = n;
|
||||
this.g = g;
|
||||
}
|
||||
|
||||
public BigInteger getN() {
|
||||
return n;
|
||||
}
|
||||
|
||||
public BigInteger getG() {
|
||||
return g;
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright (c) 2023 looly(loolly@aliyun.com)
|
||||
* Hutool is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* 同态加密算法 Paillier
|
||||
*
|
||||
* @author Revers
|
||||
*/
|
||||
package cn.hutool.crypto.asymmetric.paillier;
|
@ -1,5 +1,9 @@
|
||||
package cn.hutool.crypto.asymmetric;
|
||||
|
||||
import cn.hutool.crypto.asymmetric.paillier.Paillier;
|
||||
import cn.hutool.crypto.asymmetric.paillier.PaillierKeyPair;
|
||||
import cn.hutool.crypto.asymmetric.paillier.PaillierPrivateKey;
|
||||
import cn.hutool.crypto.asymmetric.paillier.PaillierpublicKey;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
Loading…
Reference in New Issue
Block a user