Last active
June 19, 2020 17:11
-
-
Save derfalx/b2c651b3bcfc575ac37336089f1b8503 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package tech.falx.pki.task4; | |
import org.bouncycastle.asn1.ASN1Sequence; | |
import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; | |
import org.bouncycastle.asn1.x509.*; | |
import org.bouncycastle.cert.HybridCertificateBuilder; | |
import org.bouncycastle.cert.X509CertificateHolder; | |
import org.bouncycastle.cert.X509ExtensionUtils; | |
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter; | |
import org.bouncycastle.jce.X509KeyUsage; | |
import org.bouncycastle.jce.provider.BouncyCastleProvider; | |
import org.bouncycastle.operator.ContentSigner; | |
import org.bouncycastle.operator.DigestCalculator; | |
import org.bouncycastle.operator.OperatorCreationException; | |
import org.bouncycastle.operator.bc.BcDigestCalculatorProvider; | |
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; | |
import org.bouncycastle.pqc.crypto.qtesla.QTESLAContentSigner; | |
import org.bouncycastle.pqc.crypto.qtesla.QTESLAPrivateKeyParameters; | |
import org.bouncycastle.pqc.crypto.qtesla.QTESLAPublicKeyParameters; | |
import org.bouncycastle.pqc.crypto.qtesla.QTESLASecurityCategory; | |
import org.bouncycastle.pqc.crypto.util.PrivateKeyFactory; | |
import org.bouncycastle.pqc.crypto.util.PublicKeyFactory; | |
import org.bouncycastle.pqc.jcajce.provider.BouncyCastlePQCProvider; | |
import org.bouncycastle.pqc.jcajce.provider.qtesla.BCqTESLAPrivateKey; | |
import org.bouncycastle.pqc.jcajce.provider.qtesla.BCqTESLAPublicKey; | |
import org.jetbrains.annotations.NotNull; | |
import tech.falx.pki.CryptUtils; | |
import tech.falx.pki.Utils; | |
import javax.security.auth.x500.X500Principal; | |
import java.io.IOException; | |
import java.math.BigInteger; | |
import java.security.*; | |
import java.security.cert.CertificateException; | |
import java.security.cert.X509Certificate; | |
import java.security.spec.InvalidKeySpecException; | |
import java.util.Calendar; | |
import java.util.Date; | |
/** | |
* @author falx | |
* @created 25.06.2019 | |
*/ | |
public class HybridCertGen { | |
@SuppressWarnings("Duplicates") | |
public static void main(@NotNull String[] args) throws NoSuchAlgorithmException, IOException, InvalidKeySpecException, OperatorCreationException, CertificateException { | |
Utils.printHeader("Task 4: Hybrid-CertGen"); | |
// Adding the BouncyCastle-Provider so we can use it later easier | |
Provider provider = new BouncyCastleProvider(); | |
Provider pqcProvider = new BouncyCastlePQCProvider(); | |
Utils.printInfo("RSA keys to use:", args[0], args[1]); | |
Security.addProvider(provider); | |
PublicKey pubRSAKey = CryptUtils.publicKeyFromFile(args[0], "RSA", provider); | |
PrivateKey privRSAKey = CryptUtils.privateKeyFromFile(args[1], "RSA", provider); | |
Utils.printInfo("QTesla keys to use:", args[2], args[3]); | |
BCqTESLAPublicKey pubQTeslaKey = (BCqTESLAPublicKey) CryptUtils.publicKeyFromFile( | |
args[2], | |
"qTESLA", | |
pqcProvider | |
); | |
QTESLAPublicKeyParameters pubQTeslaKeyParam =(QTESLAPublicKeyParameters) PublicKeyFactory.createKey(pubQTeslaKey.getEncoded()); | |
BCqTESLAPrivateKey privQTeslaKey = (BCqTESLAPrivateKey) CryptUtils.privateKeyFromFile( | |
args[3], | |
"qTESLA", | |
pqcProvider | |
); | |
QTESLAPrivateKeyParameters privQTeslaKeyParam = (QTESLAPrivateKeyParameters) PrivateKeyFactory.createKey(privQTeslaKey.getEncoded()); | |
String distinguishedName = args[4]; | |
Utils.printInfo("DistinguishedName to use:", distinguishedName); | |
boolean isCACert = args[5].equals("yes"); | |
Utils.printInfo("This certificate is a CA-certificate:", isCACert ? "yes" : "no"); | |
// Let's create the validity and serial | |
Date now = new Date(System.currentTimeMillis()); | |
BigInteger serialNo = new BigInteger(Long.toString(now.getTime())); | |
Calendar calendar = Calendar.getInstance(); | |
calendar.setTime(now); | |
calendar.add(Calendar.YEAR, 1); | |
Date endDate = calendar.getTime(); | |
Utils.printInfo("The start date is:\n\t" + now); | |
Utils.printInfo("The end date is:\n\t" + endDate); | |
Utils.printInfo("The serial-no is:\n\t" + serialNo); | |
X500Principal principal = new X500Principal(distinguishedName); | |
HybridCertificateBuilder builder = new HybridCertificateBuilder( | |
principal, | |
serialNo, | |
now, | |
endDate, | |
principal, | |
pubRSAKey, | |
pubQTeslaKeyParam | |
); | |
Utils.printInfo("Adding BasicConstraint to mark the Cert as end-entity"); | |
BasicConstraints basicConstraints = new BasicConstraints(isCACert); | |
builder.addExtension(Extension.basicConstraints, true, basicConstraints); | |
X509KeyUsage keyUsage; | |
if(isCACert){ | |
Utils.printInfo("Setting keyusage to:", "keyCertSign", "cRLSign"); | |
keyUsage = new X509KeyUsage(X509KeyUsage.keyCertSign | X509KeyUsage.cRLSign); | |
} else { | |
Utils.printInfo("Setting keyusage to:", "digitalsignature"); | |
keyUsage = new X509KeyUsage(X509KeyUsage.digitalSignature); | |
} | |
builder.addExtension(Extension.keyUsage, true, keyUsage); | |
if(isCACert){ | |
Utils.printInfo("Adding SubjectKeyIdentifier for the RSA key"); | |
AlgorithmIdentifier sha1Identifier = new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1); | |
DigestCalculator calculator = new BcDigestCalculatorProvider().get(sha1Identifier); | |
X509ExtensionUtils extensionUtils = new X509ExtensionUtils(calculator); | |
SubjectPublicKeyInfo publicKeyInfo = new SubjectPublicKeyInfo(ASN1Sequence.getInstance(pubRSAKey.getEncoded())); | |
SubjectKeyIdentifier ski = extensionUtils.createSubjectKeyIdentifier(publicKeyInfo); | |
builder.addExtension(Extension.subjectKeyIdentifier, false, ski); | |
} | |
Utils.printInfo("Signing and building the hybrid-certificate"); | |
ContentSigner rsaContentSigner = new JcaContentSignerBuilder("SHA256WithRSA").build(privRSAKey); | |
QTESLAContentSigner qteslaContentSigner = new QTESLAContentSigner(privQTeslaKeyParam); | |
X509CertificateHolder certHolder = builder.buildHybrid(rsaContentSigner, qteslaContentSigner); | |
X509Certificate cert = new JcaX509CertificateConverter().setProvider(provider).getCertificate(certHolder); | |
CryptUtils.certToPEM(args[6], cert); | |
} | |
} | |
/* | |
# ================================================ | |
# PKI Summer Semester 2019 | |
# - Task 4: Hybrid-CertGen | |
# ================================================ | |
[+] RSA keys to use: | |
keys/task4/PubKeyCA_E75.pem | |
keys/task4/PrivKeyCA_E75.pem | |
[+] Reading public RSA key from keys/task4/PubKeyCA_E75.pem | |
[+] Reading private RSA key from keys/task4/PrivKeyCA_E75.pem | |
[+] QTesla keys to use: | |
keys/task4/pub_CA_qTesla_E75.pem | |
keys/task4/priv_CA_qTesla_E75.pem | |
[+] Reading public qTESLA key from keys/task4/pub_CA_qTesla_E75.pem | |
[+] Reading private qTESLA key from keys/task4/priv_CA_qTesla_E75.pem | |
[+] DistinguishedName to use: | |
CN = CA75, OU = PKI, O = C75 Inc, L = Darmstadt, ST = Hessen, C = DE | |
[+] This certificate is a CA-certificate: | |
yes | |
[+] The start date is: | |
Tue Jun 25 19:41:43 CEST 2019 | |
[+] The end date is: | |
Thu Jun 25 19:41:43 CEST 2020 | |
[+] The serial-no is: | |
1561484503112 | |
[+] Adding BasicConstraint to mark the Cert as end-entity | |
[+] Setting keyusage to: | |
keyCertSign | |
cRLSign | |
[+] Adding SubjectKeyIdentifier for the RSA key | |
[+] Signing and building the hybrid-certificate | |
[+] Writing a certificate to: | |
keys/task4/CAcert_CA75.crt | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment