diff --git a/CHANGELOG.md b/CHANGELOG.md index a7d86d700..58091117d 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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) diff --git a/hutool-crypto/src/main/java/cn/hutool/crypto/asymmetric/PaillierpublicKey.java b/hutool-crypto/src/main/java/cn/hutool/crypto/asymmetric/PaillierpublicKey.java deleted file mode 100644 index 4aebdeade..000000000 --- a/hutool-crypto/src/main/java/cn/hutool/crypto/asymmetric/PaillierpublicKey.java +++ /dev/null @@ -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; - } -} diff --git a/hutool-crypto/src/main/java/cn/hutool/crypto/asymmetric/Paillier.java b/hutool-crypto/src/main/java/cn/hutool/crypto/asymmetric/paillier/Paillier.java similarity index 59% rename from hutool-crypto/src/main/java/cn/hutool/crypto/asymmetric/Paillier.java rename to hutool-crypto/src/main/java/cn/hutool/crypto/asymmetric/paillier/Paillier.java index a3baf728c..0bbf0f093 100644 --- a/hutool-crypto/src/main/java/cn/hutool/crypto/asymmetric/Paillier.java +++ b/hutool-crypto/src/main/java/cn/hutool/crypto/asymmetric/paillier/Paillier.java @@ -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 - * + *

* 加法同态,存在有效算法+,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。 - * + *

* 方案安全性可以归约到判定性合数剩余假设(Decisional Composite Residuosity Assumption, DCRA),即给定一个合数n和整数z,判定z是否在n^2下是否是n次剩余是困难的。 * 这个假设经过了几十年的充分研究,到目前为止还没有多项式时间的算法可以攻破,所以Paillier加密方案的安全性被认为相当可靠。 - * + *

* 字符串文本加解密相互配对,此时无法使用同态加法和同态乘法 * 数值类型不可使用字符串加解密 - * + *

* 公钥加密和同态加法/同态乘法运算 * 私钥解密 * @@ -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(); } } diff --git a/hutool-crypto/src/main/java/cn/hutool/crypto/asymmetric/PaillierKeyPair.java b/hutool-crypto/src/main/java/cn/hutool/crypto/asymmetric/paillier/PaillierKeyPair.java similarity index 54% rename from hutool-crypto/src/main/java/cn/hutool/crypto/asymmetric/PaillierKeyPair.java rename to hutool-crypto/src/main/java/cn/hutool/crypto/asymmetric/paillier/PaillierKeyPair.java index cc68c1b3c..a9a2c06fe 100644 --- a/hutool-crypto/src/main/java/cn/hutool/crypto/asymmetric/PaillierKeyPair.java +++ b/hutool-crypto/src/main/java/cn/hutool/crypto/asymmetric/paillier/PaillierKeyPair.java @@ -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 公钥私钥对 diff --git a/hutool-crypto/src/main/java/cn/hutool/crypto/asymmetric/PaillierPrivateKey.java b/hutool-crypto/src/main/java/cn/hutool/crypto/asymmetric/paillier/PaillierPrivateKey.java similarity index 54% rename from hutool-crypto/src/main/java/cn/hutool/crypto/asymmetric/PaillierPrivateKey.java rename to hutool-crypto/src/main/java/cn/hutool/crypto/asymmetric/paillier/PaillierPrivateKey.java index a6af60d58..1cc4eef9f 100644 --- a/hutool-crypto/src/main/java/cn/hutool/crypto/asymmetric/PaillierPrivateKey.java +++ b/hutool-crypto/src/main/java/cn/hutool/crypto/asymmetric/paillier/PaillierPrivateKey.java @@ -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; diff --git a/hutool-crypto/src/main/java/cn/hutool/crypto/asymmetric/paillier/PaillierpublicKey.java b/hutool-crypto/src/main/java/cn/hutool/crypto/asymmetric/paillier/PaillierpublicKey.java new file mode 100644 index 000000000..373c33a06 --- /dev/null +++ b/hutool-crypto/src/main/java/cn/hutool/crypto/asymmetric/paillier/PaillierpublicKey.java @@ -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; + } +} diff --git a/hutool-crypto/src/main/java/cn/hutool/crypto/asymmetric/paillier/package-info.java b/hutool-crypto/src/main/java/cn/hutool/crypto/asymmetric/paillier/package-info.java new file mode 100755 index 000000000..da0d45255 --- /dev/null +++ b/hutool-crypto/src/main/java/cn/hutool/crypto/asymmetric/paillier/package-info.java @@ -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; diff --git a/hutool-crypto/src/test/java/cn/hutool/crypto/asymmetric/PaillierTest.java b/hutool-crypto/src/test/java/cn/hutool/crypto/asymmetric/PaillierTest.java index 472129207..5aa3780b1 100644 --- a/hutool-crypto/src/test/java/cn/hutool/crypto/asymmetric/PaillierTest.java +++ b/hutool-crypto/src/test/java/cn/hutool/crypto/asymmetric/PaillierTest.java @@ -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;