密钥对制作
KeyPair 是java中的秘钥对,可以获取公私钥信息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(2048); KeyPair keyPair = keyPairGenerator.generateKeyPair();
RSAKeyPairGenerator rsaKeyPairGenerator = new RSAKeyPairGenerator();
SecureRandom random = SecureRandom.getInstanceStrong();
rsaKeyPairGenerator.initialize(2048, random); KeyPair keyPair1 = rsaKeyPairGenerator.generateKeyPair();
|
其中,在获取SecureRandom时可以选择随机算法SHA1PRNG/NativePRNG/NativePRNGBlocking/DRBG/AES128CounterMode;
java使用时可以默认选择SecureRandom.getInstanceStrong()系统自行选择
(1) SHA1PRNG
描述:基于 SHA1 的伪随机数生成器(PRNG),性能较高但安全性较弱。
适用场景:非高安全需求的场景(如测试或简单加密)。
注意:SHA1 已被证明存在碰撞漏洞,不建议用于高安全场景。
(2) NativePRNG
描述:直接调用操作系统底层的随机数生成器(如 Linux 的 /dev/urandom 或 Windows 的 CryptGenRandom)。
优点:高安全性,直接依赖操作系统提供的随机性。
适用场景:需要强加密安全性的场景(如密钥生成、SSL/TLS)。
注意:
在 Linux/macOS 上,NativePRNG 使用 /dev/urandom。
在 Windows 上,使用 CryptGenRandom API。
可能需要指定后缀(如 NativePRNGBlocking 或 NativePRNGNonBlocking,具体见下文)。
(3) NativePRNGBlocking
描述:与 NativePRNG 类似,但会阻塞直到获取足够的熵(更安全但可能较慢)。
适用场景:需要最高安全性的场景(如生成密钥对)。
(4) DRBG
描述:基于 NIST 标准的 DRBG(Deterministic Random Bit Generator)算法。
优点:符合 FIPS 标准,安全性高。
适用场景:符合 FIPS 要求的环境(如美国政府项目)。
注意:需要启用 FIPS 模式(通过 JVM 参数 -Dcom.sun.security.enableFIPS=true)。
(5) AES128CounterMode
描述:基于 AES 的计数器模式生成随机数。
优点:性能较好且安全性较高。
适用场景:需要平衡安全性和性能的场景。
证书制作
bouncycastle 制作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
| import lombok.Data; import lombok.experimental.Accessors; import org.apache.commons.codec.binary.Base64; import org.apache.commons.codec.binary.StringUtils; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter; import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder; import org.bouncycastle.operator.ContentSigner; import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; import org.bouncycastle.asn1.x500.X500Name;
import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.Security; import java.security.cert.X509Certificate; import java.math.BigInteger; import java.util.Date;
public class CertificateGenerator { static { Security.addProvider(new BouncyCastleProvider()); }
@Data @Accessors(chain = true) static class CertificateInfo { private String subject; private String issuer; private String serial; private Date notBefore; private Date notAfter; private String signatureAlgorithm = "SHA256withRSA"; }
public static void main(String[] args) throws Exception { CertificateInfo certificateInfo = new CertificateInfo(); certificateInfo.setSubject("CN=John Doe, OU=Engineering, O=MyCompany, C=US") .setIssuer("CN=John Doe, OU=Engineering, O=MyCompany, C=US") .setNotBefore(new Date(System.currentTimeMillis() - 1000L * 60 * 60 * 24)) .setNotAfter(new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 365))) ;
generate(certificateInfo); }
public static void generate(CertificateInfo certificateInfo) throws Exception { KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); keyPairGenerator.initialize(2048); KeyPair keyPair = keyPairGenerator.generateKeyPair(); X500Name subject = new X500Name(certificateInfo.getSubject()); X500Name issuer = new X500Name(certificateInfo.getIssuer());
BigInteger serial = BigInteger.valueOf(System.currentTimeMillis()); Date notBefore = certificateInfo.getNotBefore(); Date notAfter = certificateInfo.getNotAfter();
ContentSigner signer = new JcaContentSignerBuilder(certificateInfo.getSignatureAlgorithm()).build(keyPair.getPrivate());
JcaX509v3CertificateBuilder certBuilder = new JcaX509v3CertificateBuilder( issuer, serial, notBefore, notAfter, subject, keyPair.getPublic() );
X509Certificate x509Certificate = new JcaX509CertificateConverter() .setProvider(BouncyCastleProvider.PROVIDER_NAME) .getCertificate(certBuilder.build(signer));
System.out.println("Certificate generated successfully!"); x509Certificate.verify(keyPair.getPublic()); byte[] encoded = x509Certificate.getEncoded();
String privateKeyBase64 = Base64.encodeBase64String(keyPair.getPrivate().getEncoded()); String publicKeyBase64 = Base64.encodeBase64String(keyPair.getPublic().getEncoded());
String strCertData = StringUtils.newStringUtf8(Base64 .encodeBase64Chunked(encoded)); System.out.println("strCertData: " + strCertData); System.out.println("privateKeyBase64: " + privateKeyBase64); System.out.println("publicKeyBase64: " + publicKeyBase64);
System.out.println("x509Certificate: " + x509Certificate); System.out.println("x509Certificate.getPublicKey(): " + x509Certificate.getPublicKey()); }
}
|
Java内置的方法制作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
| import java.math.BigInteger; import java.security.*; import java.security.cert.X509Certificate; import java.time.Instant; import java.util.Date;
import org.apache.commons.codec.binary.Base64; import org.apache.commons.codec.binary.StringUtils; import sun.security.x509.*;
import javax.security.auth.x500.X500PrivateCredential;
public class CertificateJavaSecurity {
public static void main(String[] args) throws Exception { KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA"); keyGen.initialize(2048); KeyPair keyPair = keyGen.generateKeyPair(); PublicKey publicKey = keyPair.getPublic(); PrivateKey privateKey = keyPair.getPrivate();
X509CertInfo x509CertInfo = new X509CertInfo(); x509CertInfo.set(X509CertInfo.VERSION, new CertificateVersion(CertificateVersion.V3)); BigInteger serialNumber = new BigInteger(Long.toString(System.currentTimeMillis())); x509CertInfo.set(X509CertInfo.SERIAL_NUMBER, new CertificateSerialNumber(serialNumber));
x509CertInfo.set(X509CertInfo.ALGORITHM_ID, new CertificateAlgorithmId(AlgorithmId.get("RSA")));
x509CertInfo.set(X509CertInfo.KEY, new CertificateX509Key(keyPair.getPublic()));
X500Name owner = new X500Name("CN=MyUser,O=MyOrg,L=MyCity,C=MY"); x509CertInfo.set(X509CertInfo.SUBJECT, new CertificateSubjectName(owner)); X500Name issuer = new X500Name("CN=MyCA,O=MyOrg,L=MyCity,C=MY"); x509CertInfo.set(X509CertInfo.ISSUER, new CertificateIssuerName(issuer)); Date notBefore = Date.from(Instant.now().minusSeconds(5 * 60 * 60)); Date notAfter = Date.from(Instant.now().plusSeconds(5 * 60 * 60)); x509CertInfo.set(X509CertInfo.VALIDITY, new CertificateValidity(notBefore, notAfter));
X509Certificate x509Certificate = new X509CertImpl(x509CertInfo); x509Certificate.verify(publicKey);
X500PrivateCredential x500PrivateCredential = new X500PrivateCredential(x509Certificate, keyPair.getPrivate());
byte[] encoded = x509Certificate.getEncoded(); String strCertData = StringUtils.newStringUtf8(Base64 .encodeBase64Chunked(encoded));
System.out.println(x509Certificate.toString()); } }
|