add methods

This commit is contained in:
Looly 2021-02-26 09:11:45 +08:00
parent 4c772ead35
commit ba8b4ad760
3 changed files with 96 additions and 19 deletions

View File

@ -1,5 +1,8 @@
package cn.hutool.crypto;
import cn.hutool.core.io.IORuntimeException;
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.asn1.x9.X9ECParameters;
import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
import org.bouncycastle.crypto.params.ECDomainParameters;
@ -13,6 +16,7 @@ import org.bouncycastle.jce.spec.ECNamedCurveSpec;
import org.bouncycastle.jce.spec.ECParameterSpec;
import org.bouncycastle.math.ec.ECCurve;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;
import java.security.Key;
@ -313,4 +317,37 @@ public class BCUtil {
public static PublicKey readPemPublicKey(InputStream pemStream) {
return PemUtil.readPemPublicKey(pemStream);
}
/**
* Java中的PKCS#8格式私钥转换为OpenSSL支持的PKCS#1格式
*
* @param privateKey PKCS#8格式私钥
* @return PKCS#1格式私钥
* @since 5.5.9
*/
public static byte[] toPkcs1(PrivateKey privateKey){
final PrivateKeyInfo pkInfo = PrivateKeyInfo.getInstance(privateKey.getEncoded());
try {
return pkInfo.parsePrivateKey().toASN1Primitive().getEncoded();
} catch (IOException e) {
throw new IORuntimeException(e);
}
}
/**
* Java中的X.509格式公钥转换为OpenSSL支持的PKCS#1格式
*
* @param publicKey X.509格式公钥
* @return PKCS#1格式公钥
* @since 5.5.9
*/
public static byte[] toPkcs1(PublicKey publicKey){
final SubjectPublicKeyInfo spkInfo = SubjectPublicKeyInfo
.getInstance(publicKey.getEncoded());
try {
return spkInfo.parsePublicKey().getEncoded();
} catch (IOException e) {
throw new IORuntimeException(e);
}
}
}

View File

@ -13,6 +13,8 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.io.StringWriter;
import java.io.Writer;
import java.security.Key;
import java.security.PrivateKey;
import java.security.PublicKey;
@ -67,7 +69,8 @@ public class PemUtil {
//private
if (type.endsWith("EC PRIVATE KEY")) {
return KeyUtil.generatePrivateKey("EC", object.getContent());
}if (type.endsWith("PRIVATE KEY")) {
}
if (type.endsWith("PRIVATE KEY")) {
return KeyUtil.generateRSAPrivateKey(object.getContent());
}
@ -130,11 +133,35 @@ public class PemUtil {
}
}
/**
* 读取OpenSSL生成的ANS1格式的Pem私钥文件
*
* @param keyStream 私钥pem流
* @return {@link PrivateKey}
*/
public static PrivateKey readSm2PemPrivateKey(InputStream keyStream) {
final ECPrivateKey ecPrivateKey = ECPrivateKey.getInstance(readPem(keyStream));
return ECKeyUtil.toSm2PrivateKey(ecPrivateKey);
}
/**
* 将私钥或公钥转换为PEM格式的字符串
* @param type 密钥类型私钥公钥证书
* @param content 密钥内容
* @return PEM内容
* @since 5.5.9
*/
public static String toPem(String type, byte[] content) {
final StringWriter stringWriter = new StringWriter();
writePemObject(type, content, stringWriter);
return stringWriter.toString();
}
/**
* 写出pem密钥私钥公钥证书
*
* @param type 密钥类型私钥公钥证书
* @param content 密钥内容
* @param content 密钥内容需为PKCS#1格式
* @param keyStream pem流
* @since 5.1.6
*/
@ -142,6 +169,18 @@ public class PemUtil {
writePemObject(new PemObject(type, content), keyStream);
}
/**
* 写出pem密钥私钥公钥证书
*
* @param type 密钥类型私钥公钥证书
* @param content 密钥内容需为PKCS#1格式
* @param writer pemWriter
* @since 5.5.9
*/
public static void writePemObject(String type, byte[] content, Writer writer) {
writePemObject(new PemObject(type, content), writer);
}
/**
* 写出pem密钥私钥公钥证书
*
@ -150,25 +189,24 @@ public class PemUtil {
* @since 5.1.6
*/
public static void writePemObject(PemObjectGenerator pemObject, OutputStream keyStream) {
PemWriter writer = null;
try {
writer = new PemWriter(IoUtil.getUtf8Writer(keyStream));
writer.writeObject(pemObject);
} catch (IOException e) {
throw new IORuntimeException(e);
} finally {
IoUtil.close(writer);
}
writePemObject(pemObject, IoUtil.getUtf8Writer(keyStream));
}
/**
* 读取OpenSSL生成的ANS1格式的Pem私钥文件
* 写出pem密钥私钥公钥证书
*
* @param keyStream 私钥pem流
* @return {@link PrivateKey}
* @param pemObject pem对象包括密钥和密钥类型等信息
* @param writer pemWriter
* @since 5.5.9
*/
public static PrivateKey readSm2PemPrivateKey(InputStream keyStream){
final ECPrivateKey ecPrivateKey = ECPrivateKey.getInstance(readPem(keyStream));
return ECKeyUtil.toSm2PrivateKey(ecPrivateKey);
public static void writePemObject(PemObjectGenerator pemObject, Writer writer) {
final PemWriter pemWriter = new PemWriter(writer);
try {
pemWriter.writeObject(pemObject);
} catch (IOException e) {
throw new IORuntimeException(e);
} finally {
IoUtil.close(pemWriter);
}
}
}

View File

@ -274,7 +274,8 @@ public class SM2 extends AbstractAsymmetricCrypto<SM2> {
}
/**
* 用私钥对信息生成数字签名
* 用私钥对信息生成数字签名签名格式为ASN1<br>
* * 在硬件签名中返回结果为R+S可以通过调用{@link cn.hutool.crypto.SmUtil#rsAsn1ToPlain(byte[])}方法转换之
*
* @param data 加密数据
* @return 签名
@ -295,7 +296,8 @@ public class SM2 extends AbstractAsymmetricCrypto<SM2> {
}
/**
* 用私钥对信息生成数字签名
* 用私钥对信息生成数字签名签名格式为ASN1<br>
* 在硬件签名中返回结果为R+S可以通过调用{@link cn.hutool.crypto.SmUtil#rsAsn1ToPlain(byte[])}方法转换之
*
* @param data 被签名的数据数据
* @param id 可以为null若为null则默认withId为字节数组:"1234567812345678".getBytes()