SM2.signHex改名为signHexFromHex,原名标记废弃,避免歧义

This commit is contained in:
Looly 2024-10-30 11:56:29 +08:00
parent e8b161613d
commit 22590b51e0
5 changed files with 88 additions and 144 deletions

View File

@ -87,7 +87,7 @@ public class Hex {
* @param data 被编码的字符串 * @param data 被编码的字符串
* @return 十六进制String * @return 十六进制String
*/ */
public static String encodeStr(final String data) { public static String encodeStr(final CharSequence data) {
return encodeStr(data, CharsetUtil.UTF_8); return encodeStr(data, CharsetUtil.UTF_8);
} }
@ -98,7 +98,7 @@ public class Hex {
* @param charset 编码 * @param charset 编码
* @return 十六进制String * @return 十六进制String
*/ */
public static String encodeStr(final String data, final Charset charset) { public static String encodeStr(final CharSequence data, final Charset charset) {
return encodeStr(ByteUtil.toBytes(data, charset), true); return encodeStr(ByteUtil.toBytes(data, charset), true);
} }
@ -122,7 +122,7 @@ public class Hex {
* @param hexStr 十六进制String * @param hexStr 十六进制String
* @return 字符串 * @return 字符串
*/ */
public static String decodeStr(final String hexStr) { public static String decodeStr(final CharSequence hexStr) {
return decodeStr(hexStr, CharsetUtil.UTF_8); return decodeStr(hexStr, CharsetUtil.UTF_8);
} }
@ -133,9 +133,9 @@ public class Hex {
* @param charset 编码 * @param charset 编码
* @return 字符串 * @return 字符串
*/ */
public static String decodeStr(final String hexStr, final Charset charset) { public static String decodeStr(final CharSequence hexStr, final Charset charset) {
if (StrUtil.isEmpty(hexStr)) { if (StrUtil.isEmpty(hexStr)) {
return hexStr; return StrUtil.toStringOrNull(hexStr);
} }
return StrUtil.str(decode(hexStr), charset); return StrUtil.str(decode(hexStr), charset);
} }
@ -151,16 +151,6 @@ public class Hex {
return StrUtil.str(decode(hexData), charset); return StrUtil.str(decode(hexData), charset);
} }
/**
* 将十六进制字符串解码为byte[]
*
* @param hexStr 十六进制String
* @return byte[]
*/
public static byte[] decode(final String hexStr) {
return decode((CharSequence) hexStr);
}
/** /**
* 将十六进制字符数组转换为字节数组 * 将十六进制字符数组转换为字节数组
* *

View File

@ -475,11 +475,22 @@ public class SM2 extends AbstractAsymmetricCrypto<SM2> {
/** /**
* 用私钥对信息生成数字签名 * 用私钥对信息生成数字签名
* *
* @param dataHex 被签名的数据数据 * @param data 被签名的数据数据
* @return 签名 * @return 签名
*/ */
public String signHex(final String dataHex) { public String signHex(final byte[] data) {
return signHex(dataHex, null); return signHex(data, null);
}
/**
* 用私钥对信息生成数字签名
*
* @param data 被签名的数据数据
* @param id 可以为null若为null则默认withId为字节数组:"1234567812345678".getBytes()
* @return 签名
*/
public String signHex(final byte[] data, final byte[] id) {
return HexUtil.encodeStr(sign(data, id));
} }
/** /**
@ -493,17 +504,6 @@ public class SM2 extends AbstractAsymmetricCrypto<SM2> {
return sign(data, null); return sign(data, null);
} }
/**
* 用私钥对信息生成数字签名
*
* @param dataHex 被签名的数据数据
* @param idHex 可以为null若为null则默认withId为字节数组:"1234567812345678".getBytes()
* @return 签名
*/
public String signHex(final String dataHex, final String idHex) {
return HexUtil.encodeStr(sign(HexUtil.decode(dataHex), HexUtil.decode(idHex)));
}
/** /**
* 用私钥对信息生成数字签名签名格式为ASN1<br> * 用私钥对信息生成数字签名签名格式为ASN1<br>
* 在硬件签名中返回结果为R+S可以通过调用{@link SmUtil#rsAsn1ToPlain(byte[])}方法转换之 * 在硬件签名中返回结果为R+S可以通过调用{@link SmUtil#rsAsn1ToPlain(byte[])}方法转换之

View File

@ -16,12 +16,10 @@
package org.dromara.hutool.crypto.asymmetric; package org.dromara.hutool.crypto.asymmetric;
import org.dromara.hutool.core.codec.binary.HexUtil;
import org.dromara.hutool.core.codec.binary.Base64; import org.dromara.hutool.core.codec.binary.Base64;
import org.dromara.hutool.core.codec.binary.HexUtil;
import org.dromara.hutool.core.collection.CollUtil; import org.dromara.hutool.core.collection.CollUtil;
import org.dromara.hutool.core.io.IoUtil; import org.dromara.hutool.core.io.IoUtil;
import org.dromara.hutool.core.util.ByteUtil;
import org.dromara.hutool.core.util.CharsetUtil;
import org.dromara.hutool.crypto.CryptoException; import org.dromara.hutool.crypto.CryptoException;
import org.dromara.hutool.crypto.KeyUtil; import org.dromara.hutool.crypto.KeyUtil;
import org.dromara.hutool.crypto.SecureUtil; import org.dromara.hutool.crypto.SecureUtil;
@ -29,8 +27,9 @@ import org.dromara.hutool.crypto.SignUtil;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.InputStream; import java.io.InputStream;
import java.nio.charset.Charset; import java.security.InvalidAlgorithmParameterException;
import java.security.*; import java.security.KeyPair;
import java.security.Signature;
import java.security.cert.Certificate; import java.security.cert.Certificate;
import java.security.cert.X509Certificate; import java.security.cert.X509Certificate;
import java.security.spec.AlgorithmParameterSpec; import java.security.spec.AlgorithmParameterSpec;
@ -179,64 +178,57 @@ public class Sign extends BaseAsymmetric<Sign> {
return this; return this;
} }
// --------------------------------------------------------------------------------- Sign and Verify
/** /**
* 生成文件签名 * 获得签名对象
* *
* @param data 被签名数据 * @return {@link Signature}
* @param charset 编码
* @return 签名
* @since 5.7.0
*/ */
public byte[] sign(final String data, final Charset charset) { public Signature getSignature() {
return sign(ByteUtil.toBytes(data, charset)); return signature;
} }
/** /**
* 生成文件签名 * 设置签名
* *
* @param data 被签名数据 * @param signature 签名对象 {@link Signature}
* @return 签名 * @return 自身 {@link AsymmetricCrypto}
* @since 5.7.0
*/ */
public byte[] sign(final String data) { public Sign setSignature(final Signature signature) {
return sign(data, CharsetUtil.UTF_8); this.signature = signature;
return this;
} }
/** /**
* 生成文件签名并转为16进制字符串 * 设置{@link Certificate} 为PublicKey<br>
* 如果Certificate是X509Certificate我们需要检查是否有密钥扩展
* *
* @param data 被签名数据 * @param certificate {@link Certificate}
* @param charset 编码 * @return this
* @return 签名
* @since 5.7.0
*/ */
public String signHex(final String data, final Charset charset) { public Sign setCertificate(final Certificate certificate) {
return HexUtil.encodeStr(sign(data, charset)); // If the certificate is of type X509Certificate,
} // we should check whether it has a Key Usage
// extension marked as critical.
/** if (certificate instanceof X509Certificate) {
* 生成文件签名 // Check whether the cert has a key usage extension
* // marked as a critical extension.
* @param data 被签名数据 // The OID for KeyUsage extension is 2.5.29.15.
* @return 签名 final X509Certificate cert = (X509Certificate) certificate;
* @since 5.7.0 final Set<String> critSet = cert.getCriticalExtensionOIDs();
*/
public String signHex(final String data) { if (CollUtil.isNotEmpty(critSet) && critSet.contains("2.5.29.15")) {
return signHex(data, CharsetUtil.UTF_8); final boolean[] keyUsageInfo = cert.getKeyUsage();
} // keyUsageInfo[0] is for digitalSignature.
if ((keyUsageInfo != null) && (keyUsageInfo[0] == false)) {
/** throw new CryptoException("Wrong key usage");
* 用私钥对信息生成数字签名 }
* }
* @param data 加密数据 }
* @return 签名 this.publicKey = certificate.getPublicKey();
*/ return this;
public byte[] sign(final byte[] data) {
return sign(new ByteArrayInputStream(data), -1);
} }
// region ----- Sign and Verify
/** /**
* 生成签名并转为16进制字符串<br> * 生成签名并转为16进制字符串<br>
* *
@ -257,18 +249,7 @@ public class Sign extends BaseAsymmetric<Sign> {
* @since 5.7.0 * @since 5.7.0
*/ */
public String signHex(final InputStream data) { public String signHex(final InputStream data) {
return HexUtil.encodeStr(sign(data)); return signHex(data, -1);
}
/**
* 生成签名使用默认缓存大小 {@link IoUtil#DEFAULT_BUFFER_SIZE}
*
* @param data {@link InputStream} 数据流
* @return 签名bytes
* @since 5.7.0
*/
public byte[] sign(final InputStream data) {
return sign(data, IoUtil.DEFAULT_BUFFER_SIZE);
} }
/** /**
@ -280,10 +261,31 @@ public class Sign extends BaseAsymmetric<Sign> {
* @return 签名 * @return 签名
* @since 5.7.0 * @since 5.7.0
*/ */
public String digestHex(final InputStream data, final int bufferLength) { public String signHex(final InputStream data, final int bufferLength) {
return HexUtil.encodeStr(sign(data, bufferLength)); return HexUtil.encodeStr(sign(data, bufferLength));
} }
/**
* 用私钥对信息生成数字签名
*
* @param data 加密数据
* @return 签名
*/
public byte[] sign(final byte[] data) {
return sign(new ByteArrayInputStream(data), -1);
}
/**
* 生成签名使用默认缓存大小 {@link IoUtil#DEFAULT_BUFFER_SIZE}
*
* @param data {@link InputStream} 数据流
* @return 签名bytes
* @since 5.7.0
*/
public byte[] sign(final InputStream data) {
return sign(data, -1);
}
/** /**
* 生成签名 * 生成签名
* *
@ -339,54 +341,5 @@ public class Sign extends BaseAsymmetric<Sign> {
lock.unlock(); lock.unlock();
} }
} }
// endregion
/**
* 获得签名对象
*
* @return {@link Signature}
*/
public Signature getSignature() {
return signature;
}
/**
* 设置签名
*
* @param signature 签名对象 {@link Signature}
* @return 自身 {@link AsymmetricCrypto}
*/
public Sign setSignature(final Signature signature) {
this.signature = signature;
return this;
}
/**
* 设置{@link Certificate} 为PublicKey<br>
* 如果Certificate是X509Certificate我们需要检查是否有密钥扩展
*
* @param certificate {@link Certificate}
* @return this
*/
public Sign setCertificate(final Certificate certificate) {
// If the certificate is of type X509Certificate,
// we should check whether it has a Key Usage
// extension marked as critical.
if (certificate instanceof X509Certificate) {
// Check whether the cert has a key usage extension
// marked as a critical extension.
// The OID for KeyUsage extension is 2.5.29.15.
final X509Certificate cert = (X509Certificate) certificate;
final Set<String> critSet = cert.getCriticalExtensionOIDs();
if (CollUtil.isNotEmpty(critSet) && critSet.contains("2.5.29.15")) {
final boolean[] keyUsageInfo = cert.getKeyUsage();
// keyUsageInfo[0] is for digitalSignature.
if ((keyUsageInfo != null) && (keyUsageInfo[0] == false)) {
throw new CryptoException("Wrong key usage");
}
}
}
this.publicKey = certificate.getPublicKey();
return this;
}
} }

View File

@ -25,6 +25,7 @@ import org.dromara.hutool.crypto.bc.PemUtil;
import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import java.nio.charset.StandardCharsets;
import java.security.KeyPair; import java.security.KeyPair;
import java.security.PublicKey; import java.security.PublicKey;
@ -39,7 +40,7 @@ public class SignUtilTest {
final PublicKey publicKey = KeyUtil.generatePublicKey(SignAlgorithm.SHA256withRSA.getValue(), Base64.decode(base64)); final PublicKey publicKey = KeyUtil.generatePublicKey(SignAlgorithm.SHA256withRSA.getValue(), Base64.decode(base64));
Assertions.assertEquals(sign.getPublicKey(), publicKey); Assertions.assertEquals(sign.getPublicKey(), publicKey);
final String signHex = sign.signHex("abcd"); final String signHex = sign.signHex("abcd".getBytes(StandardCharsets.UTF_8));
Assert.notNull(signHex); Assert.notNull(signHex);
} }

View File

@ -169,7 +169,7 @@ public class SM2Test {
final SM2 sm2 = SmUtil.sm2(); final SM2 sm2 = SmUtil.sm2();
final String sign = sm2.signHex(HexUtil.encodeStr(content)); final String sign = sm2.signHex(content.getBytes(StandardCharsets.UTF_8));
final boolean verify = sm2.verifyHex(HexUtil.encodeStr(content), sign); final boolean verify = sm2.verifyHex(HexUtil.encodeStr(content), sign);
Assertions.assertTrue(verify); Assertions.assertTrue(verify);
} }
@ -226,7 +226,7 @@ public class SM2Test {
final String id = "31323334353637383132333435363738"; final String id = "31323334353637383132333435363738";
final SM2 sm2 = new SM2(d, x, y); final SM2 sm2 = new SM2(d, x, y);
final String sign = sm2.signHex(data, id); final String sign = sm2.signHex(HexUtil.decode(data), HexUtil.decode(id));
Assertions.assertTrue(sm2.verifyHex(data, sign)); Assertions.assertTrue(sm2.verifyHex(data, sign));
} }
@ -249,7 +249,7 @@ public class SM2Test {
final String sign = "DCA0E80A7F46C93714B51C3EFC55A922BCEF7ECF0FE9E62B53BA6A7438B543A76C145A452CA9036F3CB70D7E6C67D4D9D7FE114E5367A2F6F5A4D39F2B10F3D6"; final String sign = "DCA0E80A7F46C93714B51C3EFC55A922BCEF7ECF0FE9E62B53BA6A7438B543A76C145A452CA9036F3CB70D7E6C67D4D9D7FE114E5367A2F6F5A4D39F2B10F3D6";
Assertions.assertTrue(sm2.verifyHex(data, sign)); Assertions.assertTrue(sm2.verifyHex(data, sign));
final String sign2 = sm2.signHex(data, id); final String sign2 = sm2.signHex(HexUtil.decode(data), HexUtil.decode(id));
Assertions.assertTrue(sm2.verifyHex(data, sign2)); Assertions.assertTrue(sm2.verifyHex(data, sign2));
} }