6 changed files with 8 additions and 262 deletions
@ -1,93 +0,0 @@ |
|||||||
/* |
|
||||||
* Copyright 2018-2019 the original author or authors. |
|
||||||
* |
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
||||||
* you may not use this file except in compliance with the License. |
|
||||||
* You may obtain a copy of the License at |
|
||||||
* |
|
||||||
* https://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
* |
|
||||||
* Unless required by applicable law or agreed to in writing, software |
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, |
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
||||||
* See the License for the specific language governing permissions and |
|
||||||
* limitations under the License. |
|
||||||
*/ |
|
||||||
|
|
||||||
package org.springframework.cloud.configuration; |
|
||||||
|
|
||||||
import java.security.KeyPair; |
|
||||||
import java.security.KeyStore; |
|
||||||
import java.security.PrivateKey; |
|
||||||
import java.security.PublicKey; |
|
||||||
import java.security.cert.Certificate; |
|
||||||
import java.security.cert.X509Certificate; |
|
||||||
|
|
||||||
public class KeyAndCert { |
|
||||||
|
|
||||||
private KeyPair keyPair; |
|
||||||
|
|
||||||
private X509Certificate certificate; |
|
||||||
|
|
||||||
public KeyAndCert(KeyPair keyPair, X509Certificate certificate) { |
|
||||||
this.keyPair = keyPair; |
|
||||||
this.certificate = certificate; |
|
||||||
} |
|
||||||
|
|
||||||
public KeyPair keyPair() { |
|
||||||
return keyPair; |
|
||||||
} |
|
||||||
|
|
||||||
public PublicKey publicKey() { |
|
||||||
return keyPair.getPublic(); |
|
||||||
} |
|
||||||
|
|
||||||
public PrivateKey privateKey() { |
|
||||||
return keyPair.getPrivate(); |
|
||||||
} |
|
||||||
|
|
||||||
public X509Certificate certificate() { |
|
||||||
return certificate; |
|
||||||
} |
|
||||||
|
|
||||||
public String subject() { |
|
||||||
String dn = certificate.getSubjectX500Principal().getName(); |
|
||||||
int index = dn.indexOf('='); |
|
||||||
return dn.substring(index + 1); |
|
||||||
} |
|
||||||
|
|
||||||
public KeyAndCert sign(String subject) throws Exception { |
|
||||||
KeyTool tool = new KeyTool(); |
|
||||||
return tool.signCertificate(subject, this); |
|
||||||
} |
|
||||||
|
|
||||||
public KeyAndCert sign(KeyPair keyPair, String subject) throws Exception { |
|
||||||
KeyTool tool = new KeyTool(); |
|
||||||
return tool.signCertificate(keyPair, subject, this); |
|
||||||
} |
|
||||||
|
|
||||||
public KeyStore storeKeyAndCert(String keyPassword) throws Exception { |
|
||||||
KeyStore result = KeyStore.getInstance("PKCS12"); |
|
||||||
result.load(null); |
|
||||||
|
|
||||||
result.setKeyEntry(subject(), keyPair.getPrivate(), keyPassword.toCharArray(), certChain()); |
|
||||||
return result; |
|
||||||
} |
|
||||||
|
|
||||||
private Certificate[] certChain() { |
|
||||||
return new Certificate[] { certificate() }; |
|
||||||
} |
|
||||||
|
|
||||||
public KeyStore storeCert() throws Exception { |
|
||||||
return storeCert("PKCS12"); |
|
||||||
} |
|
||||||
|
|
||||||
public KeyStore storeCert(String storeType) throws Exception { |
|
||||||
KeyStore result = KeyStore.getInstance(storeType); |
|
||||||
result.load(null); |
|
||||||
|
|
||||||
result.setCertificateEntry(subject(), certificate()); |
|
||||||
return result; |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
@ -1,113 +0,0 @@ |
|||||||
/* |
|
||||||
* Copyright 2018-2019 the original author or authors. |
|
||||||
* |
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
||||||
* you may not use this file except in compliance with the License. |
|
||||||
* You may obtain a copy of the License at |
|
||||||
* |
|
||||||
* https://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
* |
|
||||||
* Unless required by applicable law or agreed to in writing, software |
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, |
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
||||||
* See the License for the specific language governing permissions and |
|
||||||
* limitations under the License. |
|
||||||
*/ |
|
||||||
|
|
||||||
package org.springframework.cloud.configuration; |
|
||||||
|
|
||||||
import java.math.BigInteger; |
|
||||||
import java.security.KeyPair; |
|
||||||
import java.security.KeyPairGenerator; |
|
||||||
import java.security.PrivateKey; |
|
||||||
import java.security.PublicKey; |
|
||||||
import java.security.SecureRandom; |
|
||||||
import java.security.cert.X509Certificate; |
|
||||||
import java.util.Date; |
|
||||||
|
|
||||||
import org.bouncycastle.asn1.DERSequence; |
|
||||||
import org.bouncycastle.asn1.x500.X500Name; |
|
||||||
import org.bouncycastle.asn1.x509.BasicConstraints; |
|
||||||
import org.bouncycastle.asn1.x509.Extension; |
|
||||||
import org.bouncycastle.asn1.x509.GeneralName; |
|
||||||
import org.bouncycastle.asn1.x509.GeneralNames; |
|
||||||
import org.bouncycastle.asn1.x509.KeyUsage; |
|
||||||
import org.bouncycastle.cert.X509CertificateHolder; |
|
||||||
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter; |
|
||||||
import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder; |
|
||||||
import org.bouncycastle.operator.ContentSigner; |
|
||||||
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; |
|
||||||
|
|
||||||
public class KeyTool { |
|
||||||
|
|
||||||
private static final long ONE_DAY = 1000L * 60L * 60L * 24L; |
|
||||||
|
|
||||||
private static final long TEN_YEARS = ONE_DAY * 365L * 10L; |
|
||||||
|
|
||||||
public KeyAndCert createCA(String ca) throws Exception { |
|
||||||
KeyPair keyPair = createKeyPair(); |
|
||||||
X509Certificate certificate = createCert(keyPair, ca); |
|
||||||
return new KeyAndCert(keyPair, certificate); |
|
||||||
} |
|
||||||
|
|
||||||
public KeyAndCert signCertificate(String subject, KeyAndCert signer) throws Exception { |
|
||||||
return signCertificate(createKeyPair(), subject, signer); |
|
||||||
} |
|
||||||
|
|
||||||
public KeyAndCert signCertificate(KeyPair keyPair, String subject, KeyAndCert signer) throws Exception { |
|
||||||
X509Certificate certificate = createCert(keyPair.getPublic(), signer.privateKey(), signer.subject(), subject); |
|
||||||
KeyAndCert result = new KeyAndCert(keyPair, certificate); |
|
||||||
|
|
||||||
return result; |
|
||||||
} |
|
||||||
|
|
||||||
public KeyPair createKeyPair() throws Exception { |
|
||||||
return createKeyPair(1024); |
|
||||||
} |
|
||||||
|
|
||||||
public KeyPair createKeyPair(int keySize) throws Exception { |
|
||||||
KeyPairGenerator gen = KeyPairGenerator.getInstance("RSA"); |
|
||||||
gen.initialize(keySize, new SecureRandom()); |
|
||||||
return gen.generateKeyPair(); |
|
||||||
} |
|
||||||
|
|
||||||
public X509Certificate createCert(KeyPair keyPair, String ca) throws Exception { |
|
||||||
JcaX509v3CertificateBuilder builder = certBuilder(keyPair.getPublic(), ca, ca); |
|
||||||
builder.addExtension(Extension.keyUsage, true, new KeyUsage(KeyUsage.keyCertSign)); |
|
||||||
builder.addExtension(Extension.basicConstraints, false, new BasicConstraints(true)); |
|
||||||
|
|
||||||
return signCert(builder, keyPair.getPrivate()); |
|
||||||
} |
|
||||||
|
|
||||||
public X509Certificate createCert(PublicKey publicKey, PrivateKey privateKey, String issuer, String subject) |
|
||||||
throws Exception { |
|
||||||
JcaX509v3CertificateBuilder builder = certBuilder(publicKey, issuer, subject); |
|
||||||
builder.addExtension(Extension.keyUsage, true, new KeyUsage(KeyUsage.digitalSignature)); |
|
||||||
builder.addExtension(Extension.basicConstraints, false, new BasicConstraints(false)); |
|
||||||
|
|
||||||
GeneralName[] names = new GeneralName[] { new GeneralName(GeneralName.dNSName, "localhost") }; |
|
||||||
builder.addExtension(Extension.subjectAlternativeName, false, GeneralNames.getInstance(new DERSequence(names))); |
|
||||||
|
|
||||||
return signCert(builder, privateKey); |
|
||||||
} |
|
||||||
|
|
||||||
private JcaX509v3CertificateBuilder certBuilder(PublicKey publicKey, String issuer, String subject) { |
|
||||||
X500Name issuerName = new X500Name(String.format("dc=%s", issuer)); |
|
||||||
X500Name subjectName = new X500Name(String.format("dc=%s", subject)); |
|
||||||
|
|
||||||
long now = System.currentTimeMillis(); |
|
||||||
BigInteger serialNum = BigInteger.valueOf(now); |
|
||||||
Date notBefore = new Date(now - ONE_DAY); |
|
||||||
Date notAfter = new Date(now + TEN_YEARS); |
|
||||||
|
|
||||||
return new JcaX509v3CertificateBuilder(issuerName, serialNum, notBefore, notAfter, subjectName, publicKey); |
|
||||||
} |
|
||||||
|
|
||||||
private X509Certificate signCert(JcaX509v3CertificateBuilder builder, PrivateKey privateKey) throws Exception { |
|
||||||
ContentSigner signer = new JcaContentSignerBuilder("SHA256WithRSA").build(privateKey); |
|
||||||
X509CertificateHolder holder = builder.build(signer); |
|
||||||
|
|
||||||
return new JcaX509CertificateConverter().getCertificate(holder); |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
Binary file not shown.
Binary file not shown.
Loading…
Reference in new issue