|
Play Framework/Scala example source code file (FakeKeyStore.scala)
The FakeKeyStore.scala Play Framework example source code/* * Copyright (C) 2009-2013 Typesafe Inc. <http://www.typesafe.com> */ package play.core.server.ssl import play.api.{ Play, Logger, Application } import java.security.{ KeyStore, SecureRandom, KeyPairGenerator, KeyPair } import sun.security.x509._ import java.util.Date import java.math.BigInteger import java.security.cert.{ CertPathValidatorException, X509Certificate } import java.io.{ File, FileInputStream, FileOutputStream } import javax.net.ssl.KeyManagerFactory import scala.util.control.NonFatal import scala.util.Properties.isJavaAtLeast import scala.util.{ Failure, Success, Try } import play.utils.PlayIO import java.security.interfaces.RSAPublicKey /** * A fake key store */ object FakeKeyStore { val GeneratedKeyStore = "conf/generated.keystore" val DnName = "CN=localhost, OU=Unit Testing, O=Mavericks, L=Moon Base 1, ST=Cyberspace, C=CY" def shouldGenerate(keyStoreFile: File): Boolean = { import scala.collection.JavaConverters._ if (!keyStoreFile.exists()) { return true } // Should regenerate if we find an unacceptably weak key in there. val store = KeyStore.getInstance("JKS") val in = new FileInputStream(keyStoreFile) try { store.load(in, "".toCharArray) } finally { PlayIO.closeQuietly(in) } store.aliases().asScala.foreach { alias => Option(store.getCertificate(alias)).map { c => val key: RSAPublicKey = c.getPublicKey.asInstanceOf[RSAPublicKey] if (key.getModulus.bitLength < 2048) { return true } } } false } def keyManagerFactory(appPath: File): Try[KeyManagerFactory] = { try { val keyStore = KeyStore.getInstance("JKS") val keyStoreFile = new File(appPath, GeneratedKeyStore) if (shouldGenerate(keyStoreFile)) { Play.logger.info("Generating HTTPS key pair in " + keyStoreFile.getAbsolutePath + " - this may take some time. If nothing happens, try moving the mouse/typing on the keyboard to generate some entropy.") // Generate the key pair val keyPairGenerator = KeyPairGenerator.getInstance("RSA") keyPairGenerator.initialize(2048) // 2048 is the NIST acceptable key length until 2030 val keyPair = keyPairGenerator.generateKeyPair() // Generate a self signed certificate val cert = createSelfSignedCertificate(keyPair) // Create the key store, first set the store pass keyStore.load(null, "".toCharArray) keyStore.setKeyEntry("playgenerated", keyPair.getPrivate, "".toCharArray, Array(cert)) keyStore.setCertificateEntry("playgeneratedtrusted", cert) val out = new FileOutputStream(keyStoreFile) try { keyStore.store(out, "".toCharArray) } finally { PlayIO.closeQuietly(out) } } else { val in = new FileInputStream(keyStoreFile) try { keyStore.load(in, "".toCharArray) } finally { PlayIO.closeQuietly(in) } } // Load the key and certificate into a key manager factory val kmf = KeyManagerFactory.getInstance("SunX509") kmf.init(keyStore, "".toCharArray) Success(kmf) } catch { case NonFatal(e) => { Failure(new Exception("Error loading fake key store", e)) } } } def createSelfSignedCertificate(keyPair: KeyPair): X509Certificate = { val certInfo = new X509CertInfo() // Serial number and version certInfo.set(X509CertInfo.SERIAL_NUMBER, new CertificateSerialNumber(new BigInteger(64, new SecureRandom()))) certInfo.set(X509CertInfo.VERSION, new CertificateVersion(CertificateVersion.V3)) // Validity val validFrom = new Date() val validTo = new Date(validFrom.getTime + 50l * 365l * 24l * 60l * 60l * 1000l) val validity = new CertificateValidity(validFrom, validTo) certInfo.set(X509CertInfo.VALIDITY, validity) // Subject and issuer // Note: CertificateSubjectName and CertificateIssuerName are removed in Java 8 // and when setting the subject or issuer just the X500Name should be used. val owner = new X500Name(DnName) val justName = isJavaAtLeast("1.8") certInfo.set(X509CertInfo.SUBJECT, if (justName) owner else new CertificateSubjectName(owner)) certInfo.set(X509CertInfo.ISSUER, if (justName) owner else new CertificateIssuerName(owner)) // Key and algorithm certInfo.set(X509CertInfo.KEY, new CertificateX509Key(keyPair.getPublic)) val algorithm = new AlgorithmId(AlgorithmId.sha1WithRSAEncryption_oid) certInfo.set(X509CertInfo.ALGORITHM_ID, new CertificateAlgorithmId(algorithm)) // Create a new certificate and sign it val cert = new X509CertImpl(certInfo) cert.sign(keyPair.getPrivate, "SHA1withRSA") // Since the SHA1withRSA provider may have a different algorithm ID to what we think it should be, // we need to reset the algorithm ID, and resign the certificate val actualAlgorithm = cert.get(X509CertImpl.SIG_ALG).asInstanceOf[AlgorithmId] certInfo.set(CertificateAlgorithmId.NAME + "." + CertificateAlgorithmId.ALGORITHM, actualAlgorithm) val newCert = new X509CertImpl(certInfo) newCert.sign(keyPair.getPrivate, "SHA1withRSA") newCert } } Other Play Framework source code examplesHere is a short list of links related to this Play Framework FakeKeyStore.scala source code file: |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.