May 30, 2018

How to Read PEM PKCS#1 or PKCS#8 Encoded Private Key In Java

import java.io.InputStream;
import java.math.BigInteger;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.RSAPrivateCrtKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;

import org.junit.Ignore;
import org.junit.Test;

import sun.security.util.DerInputStream;
import sun.security.util.DerValue;

public class PEMTest {

    // (PKCS#1 has the 'BEGIN RSA PRIVATE KEY' header while PKCS#8 has the 'BEGIN PRIVATE KEY' header)
    @Test
    public void readPrivateKeyPKCS1PEM() throws Exception {
        String content = new String(
                Files.readAllBytes(Paths.get(ClassLoader.getSystemResource("server.key.pkcs1.pem").toURI())));
        content = content.replaceAll("\\n", "").replace("-----BEGIN RSA PRIVATE KEY-----", "")
                .replace("-----END RSA PRIVATE KEY-----", "");
        System.out.println("'" + content + "'");
        byte[] bytes = Base64.getDecoder().decode(content);

        DerInputStream derReader = new DerInputStream(bytes);
        DerValue[] seq = derReader.getSequence(0);
        // skip version seq[0];
        BigInteger modulus = seq[1].getBigInteger();
        BigInteger publicExp = seq[2].getBigInteger();
        BigInteger privateExp = seq[3].getBigInteger();
        BigInteger prime1 = seq[4].getBigInteger();
        BigInteger prime2 = seq[5].getBigInteger();
        BigInteger exp1 = seq[6].getBigInteger();
        BigInteger exp2 = seq[7].getBigInteger();
        BigInteger crtCoef = seq[8].getBigInteger();

        RSAPrivateCrtKeySpec keySpec =
                new RSAPrivateCrtKeySpec(modulus, publicExp, privateExp, prime1, prime2, exp1, exp2, crtCoef);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
        System.out.println(privateKey);
    }

    // (PKCS#1 has the 'BEGIN RSA PRIVATE KEY' header while PKCS#8 has the 'BEGIN PRIVATE KEY' header)
    @Test
    public void readPrivateKeyPKCS8PEM() throws Exception {
        String content = new String(
                Files.readAllBytes(Paths.get(ClassLoader.getSystemResource("server.key.pkcs8.pem").toURI())));
        content = content.replaceAll("\\n", "").replace("-----BEGIN PRIVATE KEY-----", "")
                .replace("-----END PRIVATE KEY-----", "");
        System.out.println("'" + content + "'");
        byte[] bytes = Base64.getDecoder().decode(content);

        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(bytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
        System.out.println(privateKey);
    }
}

How to Read PEM or DER Encoded Certificate In Java

import java.io.InputStream;
import java.math.BigInteger;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.RSAPrivateCrtKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;

import org.junit.Test;

public class PEMTest {

    /**
     * 

* In the case of a certificate factory for X.509 certificates, the certificate provided in {@code inStream} must be * DER-encoded and may be supplied in binary or printable (Base64) encoding. If the certificate is provided in * Base64 encoding, it must be bounded at the beginning by -----BEGIN CERTIFICATE-----, and must be bounded at the * end by -----END CERTIFICATE-----. * * @throws Exception */ @Test public void readX509Certificate() throws Exception { CertificateFactory factory = CertificateFactory.getInstance("X.509"); InputStream input = ClassLoader.getSystemResourceAsStream("server.cert.pem"); X509Certificate cert = (X509Certificate) factory.generateCertificate(input); System.out.println(cert); } }

How to Create a X509 Certificate in Java without BouncyCastle?

Introduction

The Java Keytool project has most of the code to create x509 certificates in java, but it has dependency to sun class, which are deprecated, which means that they can change. So be carefully to test this code for different JRE before going into production.

How to Create a X509 Certificate in Java without BouncyCastle?

import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.SignatureException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Vector;

import sun.security.util.ObjectIdentifier;
import sun.security.x509.AccessDescription;
import sun.security.x509.AlgorithmId;
import sun.security.x509.AuthorityInfoAccessExtension;
import sun.security.x509.AuthorityKeyIdentifierExtension;
import sun.security.x509.BasicConstraintsExtension;
import sun.security.x509.CRLDistributionPointsExtension;
import sun.security.x509.CertificateAlgorithmId;
import sun.security.x509.CertificateExtensions;
import sun.security.x509.CertificateSerialNumber;
import sun.security.x509.CertificateValidity;
import sun.security.x509.CertificateVersion;
import sun.security.x509.CertificateX509Key;
import sun.security.x509.DNSName;
import sun.security.x509.DistributionPoint;
import sun.security.x509.ExtendedKeyUsageExtension;
import sun.security.x509.GeneralName;
import sun.security.x509.GeneralNames;
import sun.security.x509.KeyIdentifier;
import sun.security.x509.KeyUsageExtension;
import sun.security.x509.SerialNumber;
import sun.security.x509.SubjectAlternativeNameExtension;
import sun.security.x509.SubjectKeyIdentifierExtension;
import sun.security.x509.URIName;
import sun.security.x509.X500Name;
import sun.security.x509.X509CertImpl;
import sun.security.x509.X509CertInfo;

@SuppressWarnings("restriction")
public class X509CertificateTest {

    public X509Certificate createX509Certificate(X500Name subject, X500Name issuer, Date validityFrom, Date validityTo,
            PublicKey publicKey, PrivateKey signingPrivateKey, PublicKey signingPublicKey, String algorithm)
            throws CertificateException, IOException, InvalidKeyException, NoSuchAlgorithmException,
            NoSuchProviderException, SignatureException {

        X509CertInfo info = new X509CertInfo();
        info.set(X509CertInfo.VERSION, new CertificateVersion(CertificateVersion.V3));
        info.set(X509CertInfo.SERIAL_NUMBER, new CertificateSerialNumber(1));
        info.set(X509CertInfo.ALGORITHM_ID, new CertificateAlgorithmId(AlgorithmId.get(algorithm)));
        info.set(X509CertInfo.SUBJECT, subject);
        info.set(X509CertInfo.KEY, new CertificateX509Key(publicKey));
        info.set(X509CertInfo.VALIDITY, new CertificateValidity(validityFrom, validityTo));
        info.set(X509CertInfo.ISSUER, issuer);

        // X509v3 extensions
        CertificateExtensions exts = new CertificateExtensions();

        // Extensions[1]: Authority Information Access
        List accDescr = new ArrayList<>();
        String urlCA = "http://magnuskkarlsson.se/ca.cer";
        String urlOCSP = "http://magnuskkarlsson.se/ocsp";
        accDescr.add(new AccessDescription(AccessDescription.Ad_CAISSUERS_Id, new GeneralName(new URIName(urlCA))));
        accDescr.add(new AccessDescription(AccessDescription.Ad_OCSP_Id, new GeneralName(new URIName(urlOCSP))));
        exts.set(AuthorityInfoAccessExtension.NAME, new AuthorityInfoAccessExtension(accDescr));

        // Extensions[2]: X509v3 Authority Key Identifier
        exts.set(AuthorityKeyIdentifierExtension.NAME,
                new AuthorityKeyIdentifierExtension(new KeyIdentifier(signingPublicKey),
                        new GeneralNames().add(new GeneralName(subject)), new SerialNumber(1)));

        // Extensions[3]: X509v3 Basic Constraints: critical=true, ca=false, pathLen=-1=undefined
        exts.set(BasicConstraintsExtension.NAME, new BasicConstraintsExtension(true, false, -1));

        // Extensions[4]: X509v3 CRL Distribution Points
        List cdp = new ArrayList<>();
        String urlCRL = "http://magnuskkarlsson.se/ca.crl";
        cdp.add(new DistributionPoint(new GeneralNames().add(new GeneralName(new URIName(urlCRL))), null, null));
        exts.set(CRLDistributionPointsExtension.NAME, new CRLDistributionPointsExtension(cdp));

        // Extensions[5]: X509v3 Extended Key Usage
        Vector keyUsages = new Vector<>();
        // OID defined in RFC 3280 Sections 4.2.1.13
        // more from http://www.alvestrand.no/objectid/1.3.6.1.5.5.7.3.html
        // serverAuth
        keyUsages.addElement(ObjectIdentifier.newInternal(new int[] { 1, 3, 6, 1, 5, 5, 7, 3, 1 }));
        // clientAuth
        keyUsages.addElement(ObjectIdentifier.newInternal(new int[] { 1, 3, 6, 1, 5, 5, 7, 3, 2 }));
        exts.set(ExtendedKeyUsageExtension.NAME, new ExtendedKeyUsageExtension(keyUsages));

        // Extensions[6]: X509v3 Key Usage
        KeyUsageExtension keyUsage = new KeyUsageExtension();
        keyUsage.set(KeyUsageExtension.DIGITAL_SIGNATURE, Boolean.TRUE);
        keyUsage.set(KeyUsageExtension.NON_REPUDIATION, Boolean.FALSE);
        keyUsage.set(KeyUsageExtension.KEY_ENCIPHERMENT, Boolean.TRUE);
        keyUsage.set(KeyUsageExtension.DATA_ENCIPHERMENT, Boolean.FALSE);
        keyUsage.set(KeyUsageExtension.KEY_AGREEMENT, Boolean.FALSE);
        keyUsage.set(KeyUsageExtension.KEY_CERTSIGN, Boolean.FALSE);
        keyUsage.set(KeyUsageExtension.CRL_SIGN, Boolean.FALSE);
        keyUsage.set(KeyUsageExtension.ENCIPHER_ONLY, Boolean.FALSE);
        keyUsage.set(KeyUsageExtension.DECIPHER_ONLY, Boolean.FALSE);
        exts.set(KeyUsageExtension.NAME, keyUsage);

        // Extensions[7]: Subject Alternative Name
        String urlSAN = "magnuskkarlsson.com";
        exts.set(SubjectAlternativeNameExtension.NAME,
                new SubjectAlternativeNameExtension(new GeneralNames().add(new GeneralName(new DNSName(urlSAN)))));

        // Extensions[8]: X509v3 Subject Key Identifier
        exts.set(SubjectKeyIdentifierExtension.NAME,
                new SubjectKeyIdentifierExtension(new KeyIdentifier(publicKey).getIdentifier()));

        info.set(X509CertInfo.EXTENSIONS, exts);

        // Sign the certificate with the CA private key
        X509CertImpl cert = new X509CertImpl(info);
        cert.sign(signingPrivateKey, algorithm);

        return cert;
    }

    public X500Name createX500Name(String commonName, String organizationUnit, String organizationName,
            String localityName, String stateName, String country) throws IOException {

        return new X500Name(commonName, organizationUnit, organizationName, localityName, stateName, country);
    }

    public Date[] createValidity(int days) {
        Date from = new Date();
        Date to = new Date(from.getTime() + days * 86400000l);
        return new Date[] { from, to };
    }

    public KeyPair generateKeyPair() throws NoSuchAlgorithmException {
        KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
        keyGen.initialize(2048, new SecureRandom());
        return keyGen.generateKeyPair();
    }

    public static void main(String[] args) throws Exception {
        //        CertificateFactory factory = CertificateFactory.getInstance("X.509");
        //        InputStream input = ClassLoader.getSystemResourceAsStream("server-v3.cert.pem");
        //        X509Certificate certDemo = (X509Certificate) factory.generateCertificate(input);
        //        System.out.println(certDemo);

        X509CertificateTest test = new X509CertificateTest();
        X500Name subject = test.createX500Name("localhost", "Purch", "Onizuka, Inc.", "Palo Alto", "California", "CH");
        Date[] validity = test.createValidity(730);
        KeyPair keyPair = test.generateKeyPair();
        X509Certificate cert = test.createX509Certificate(subject, subject, validity[0], validity[1],
                keyPair.getPublic(), keyPair.getPrivate(), keyPair.getPublic(), "SHA256withRSA");
        System.out.println(cert);
    }
}

And when run

[
[
  Version: V3
  Subject: CN=localhost, OU=Purch, O="Onizuka, Inc.", L=Palo Alto, ST=California, C=CH
  Signature Algorithm: SHA256withRSA, OID = 1.2.840.113549.1.1.11

  Key:  Sun RSA public key, 2048 bits
  modulus: 16430622413258256674241974707951685615738697152316908673861521954949249341917487321969963974880523193055015435475912265313655167640567326771003684773855144686669652477201074611376490251544635379047537527674776936600766762870067059060115972142637033253593758480242365775073879800299177911290829460272374213329378851325135207593915369295651052987402058272708938961270470497580241134442791917877474961958209709747980260907545128710289887887982830065299918209286621365319016851187102417429903048397749408363510478403654647568673004684653502196209388803336825940342089023016860111125056634847644257184487730090507480997167
  public exponent: 65537
  Validity: [From: Wed May 30 13:38:49 CEST 2018,
               To: Fri May 29 13:38:49 CEST 2020]
  Issuer: CN=localhost, OU=Purch, O="Onizuka, Inc.", L=Palo Alto, ST=California, C=CH
  SerialNumber: [    01]

Certificate Extensions: 8
[1]: ObjectId: 1.3.6.1.5.5.7.1.1 Criticality=false
AuthorityInfoAccess [
  [
   accessMethod: caIssuers
   accessLocation: URIName: http://magnuskkarlsson.se/ca.cer
, 
   accessMethod: ocsp
   accessLocation: URIName: http://magnuskkarlsson.se/ocsp
]
]

[2]: ObjectId: 2.5.29.35 Criticality=false
AuthorityKeyIdentifier [
KeyIdentifier [
0000: 18 B5 68 3F 35 5A 1B 48   5F 9F B3 C3 3E AB E3 CA  ..h?5Z.H_...>...
0010: 83 FB 9E 47                                        ...G
]
[CN=localhost, OU=Purch, O="Onizuka, Inc.", L=Palo Alto, ST=California, C=CH]
SerialNumber: [    01]
]

[3]: ObjectId: 2.5.29.19 Criticality=true
BasicConstraints:[
  CA:false
  PathLen: undefined
]

[4]: ObjectId: 2.5.29.31 Criticality=false
CRLDistributionPoints [
  [DistributionPoint:
     [URIName: http://magnuskkarlsson.se/ca.crl]
]]

[5]: ObjectId: 2.5.29.37 Criticality=false
ExtendedKeyUsages [
  serverAuth
  clientAuth
]

[6]: ObjectId: 2.5.29.15 Criticality=true
KeyUsage [
  DigitalSignature
  Key_Encipherment
]

[7]: ObjectId: 2.5.29.17 Criticality=false
SubjectAlternativeName [
  DNSName: magnuskkarlsson.com
]

[8]: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: 18 B5 68 3F 35 5A 1B 48   5F 9F B3 C3 3E AB E3 CA  ..h?5Z.H_...>...
0010: 83 FB 9E 47                                        ...G
]
]

]
  Algorithm: [SHA256withRSA]
  Signature:
0000: 58 62 47 8E 55 6B 17 15   37 E9 E9 C3 2B E0 9A 71  XbG.Uk..7...+..q
0010: 11 29 04 F3 39 4E 87 DB   5B 12 73 79 2D 66 76 B3  .)..9N..[.sy-fv.
0020: E0 DD 4A F3 09 39 DF 5A   54 68 69 A7 18 44 F7 39  ..J..9.ZThi..D.9
0030: 21 02 52 6C 1B A8 87 F6   28 BD F7 B2 86 08 43 8C  !.Rl....(.....C.
0040: 62 E1 10 EB 7E 3B FB 4D   5B F3 B8 93 F9 EC 67 13  b....;.M[.....g.
0050: 11 EB 99 88 DC CA 8D 48   83 9B 4B B7 6C 4C 7E 99  .......H..K.lL..
0060: C7 9B 16 69 9E EF 20 A0   5D 55 09 EF 75 99 87 5A  ...i.. .]U..u..Z
0070: 33 26 56 E1 33 EB A7 83   54 9F 1B 4A 49 02 1E F8  3&V.3...T..JI...
0080: 95 91 99 C3 48 D2 1A C3   3A 3A 8F 99 61 77 7D 7F  ....H...::..aw..
0090: D2 0A 85 DA 86 F6 DD 06   32 D0 8D 8D 8E 76 AA 16  ........2....v..
00A0: 19 71 79 3A C1 2A 57 DD   E9 C4 AD 48 CB 87 29 EF  .qy:.*W....H..).
00B0: 13 99 BA 9E 8A 3F 2E 0C   64 22 3E 66 B3 A7 2C 69  .....?..d">f..,i
00C0: E4 94 63 BB 89 CF 98 45   DE 89 25 5C 0F 1E F1 44  ..c....E..%\...D
00D0: 99 B2 A9 9A 73 64 20 F6   B1 55 EE B7 4C 68 96 F3  ....sd ..U..Lh..
00E0: 84 47 C1 D6 F8 FB 76 11   44 71 43 01 72 F5 A0 C2  .G....v.DqC.r...
00F0: F1 86 F0 FC 6D 9D 05 4A   BB 0A 88 C7 ED 4B 5A 4B  ....m..J.....KZK

]

May 16, 2018

How to Create a Certificate Signature Request (CSR) in Java

import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.Signature;

import sun.security.pkcs10.PKCS10;
import sun.security.x509.X500Name;

public class GenerateCSR {

    // Collision DO NOT USE public static final String SHA1withRSA = "SHA1withRSA";
    public static final String SHA256withRSA = "SHA256withRSA";
    public static final String SHA384withRSA = "SHA384withRSA";
    public static final String SHA512withRSA = "SHA512withRSA";

    public static void main(String[] args) throws Exception {
        // Generate key pair
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
        keyPairGenerator.initialize(2048, new SecureRandom());
        KeyPair keyPair = keyPairGenerator.genKeyPair();
        PrivateKey privateKey = keyPair.getPrivate();
        PublicKey publicKey = keyPair.getPublic();

        // Subject DN
        String commonName = "Vivette Davis", organizationUnit = "Purchasing", organizationName = "Onizuka, Inc.",
                localityName = "Palo Alto", stateName = "California", country = "CH";
        X500Name x500Name =
                new X500Name(commonName, organizationUnit, organizationName, localityName, stateName, country);

        // Generate PKCS10 certificate request
        PKCS10 pkcs10 = new PKCS10(publicKey);
        Signature signature = Signature.getInstance("SHA256withRSA");
        signature.initSign(privateKey);
        pkcs10.encodeAndSign(x500Name, signature);

        ByteArrayOutputStream bs = new ByteArrayOutputStream();
        pkcs10.print(new PrintStream(bs));
        byte[] csr = bs.toByteArray();

        System.out.println(new String(csr));
    }
}

And when run

-----BEGIN NEW CERTIFICATE REQUEST-----
MIICwDCCAagCAQAwezELMAkGA1UEBhMCQ0gxEzARBgNVBAgTCkNhbGlmb3JuaWEx
EjAQBgNVBAcTCVBhbG8gQWx0bzEWMBQGA1UEChMNT25penVrYSwgSW5jLjETMBEG
A1UECxMKUHVyY2hhc2luZzEWMBQGA1UEAxMNVml2ZXR0ZSBEYXZpczCCASIwDQYJ
KoZIhvcNAQEBBQADggEPADCCAQoCggEBAJKD4TawNfl1nb4MQ43NZVr6aIQHyTKn
vry319KCRn5lNeYLb5atU6uKdf3Arbqr0evMFf76yzL9kjE5WL3bbYAXaVQoRkzu
sB/Ot+L0G9u3ezTjHj0Cry4bOGBV3Qny38C6jTso5xMnJH3Z2GT3Qo3ldhPA6a8j
iFF6QxgMwZvr29HFJ97170EF5YzRBCtDkrNVGVnVvIwjaXhgl2jfaZ2nCwvMPM8D
FobiO6HH2OdXmBhjrZKgldRsm1PWnBk/T8TzN1UoNZkLNxoWz0X+OdgQwTkJNqgo
O9UUtlpinJ9uMVFKVUoNx9AaTLrrMvOzYMN2RnHiDndEoZtmY9nP500CAwEAAaAA
MA0GCSqGSIb3DQEBCwUAA4IBAQB53BmcugvXl/HYgdkVGLKZYlZLdJKi9amfY8IJ
yKtBXRvzqUg7oJTtnXBTxjGKx+lldZQlmFULBTzUTiGsEBIgV9FytSZ/ef0VN7AK
fzKF+17CRfuz4uk1syTnLgiBV91R9bDccVetRTk8F8H0MVj/Fdr9KZv6WSSVWNJr
bCQHZEQZhZM5U/3CDvZm9ivnowiwma55OnsyF3LmiawgMEHTazM/EHF82IK0Smu2
oSYxfuT8OvNnpRkdOnDRBpUj45PhORrQBelMJ5H1mgalInLMlVFypNcvfe+jYJ/6
YnwlX9BWga+av6QPzDxrE2amwwXq+gCuz7tIaWh5UzPs8alK
-----END NEW CERTIFICATE REQUEST-----

And to verify with openssl, where you see the Subject, Key Length and Signature Algorithm.

$ openssl req -text -noout -in 1.csr.pem
Certificate Request:
    Data:
        Version: 0 (0x0)
        Subject: C=CH, ST=California, L=Palo Alto, O=Onizuka, Inc., OU=Purchasing, CN=Vivette Davis
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:92:83:e1:36:b0:35:f9:75:9d:be:0c:43:8d:cd:
                    65:5a:fa:68:84:07:c9:32:a7:be:bc:b7:d7:d2:82:
                    46:7e:65:35:e6:0b:6f:96:ad:53:ab:8a:75:fd:c0:
                    ad:ba:ab:d1:eb:cc:15:fe:fa:cb:32:fd:92:31:39:
                    58:bd:db:6d:80:17:69:54:28:46:4c:ee:b0:1f:ce:
                    b7:e2:f4:1b:db:b7:7b:34:e3:1e:3d:02:af:2e:1b:
                    38:60:55:dd:09:f2:df:c0:ba:8d:3b:28:e7:13:27:
                    24:7d:d9:d8:64:f7:42:8d:e5:76:13:c0:e9:af:23:
                    88:51:7a:43:18:0c:c1:9b:eb:db:d1:c5:27:de:f5:
                    ef:41:05:e5:8c:d1:04:2b:43:92:b3:55:19:59:d5:
                    bc:8c:23:69:78:60:97:68:df:69:9d:a7:0b:0b:cc:
                    3c:cf:03:16:86:e2:3b:a1:c7:d8:e7:57:98:18:63:
                    ad:92:a0:95:d4:6c:9b:53:d6:9c:19:3f:4f:c4:f3:
                    37:55:28:35:99:0b:37:1a:16:cf:45:fe:39:d8:10:
                    c1:39:09:36:a8:28:3b:d5:14:b6:5a:62:9c:9f:6e:
                    31:51:4a:55:4a:0d:c7:d0:1a:4c:ba:eb:32:f3:b3:
                    60:c3:76:46:71:e2:0e:77:44:a1:9b:66:63:d9:cf:
                    e7:4d
                Exponent: 65537 (0x10001)
        Attributes:
            a0:00
    Signature Algorithm: sha256WithRSAEncryption
         79:dc:19:9c:ba:0b:d7:97:f1:d8:81:d9:15:18:b2:99:62:56:
         4b:74:92:a2:f5:a9:9f:63:c2:09:c8:ab:41:5d:1b:f3:a9:48:
         3b:a0:94:ed:9d:70:53:c6:31:8a:c7:e9:65:75:94:25:98:55:
         0b:05:3c:d4:4e:21:ac:10:12:20:57:d1:72:b5:26:7f:79:fd:
         15:37:b0:0a:7f:32:85:fb:5e:c2:45:fb:b3:e2:e9:35:b3:24:
         e7:2e:08:81:57:dd:51:f5:b0:dc:71:57:ad:45:39:3c:17:c1:
         f4:31:58:ff:15:da:fd:29:9b:fa:59:24:95:58:d2:6b:6c:24:
         07:64:44:19:85:93:39:53:fd:c2:0e:f6:66:f6:2b:e7:a3:08:
         b0:99:ae:79:3a:7b:32:17:72:e6:89:ac:20:30:41:d3:6b:33:
         3f:10:71:7c:d8:82:b4:4a:6b:b6:a1:26:31:7e:e4:fc:3a:f3:
         67:a5:19:1d:3a:70:d1:06:95:23:e3:93:e1:39:1a:d0:05:e9:
         4c:27:91:f5:9a:06:a5:22:72:cc:95:51:72:a4:d7:2f:7d:ef:
         a3:60:9f:fa:62:7c:25:5f:d0:56:81:af:9a:bf:a4:0f:cc:3c:
         6b:13:66:a6:c3:05:ea:fa:00:ae:cf:bb:48:69:68:79:53:33:
         ec:f1:a9:4a

May 4, 2018

Eight new Spectre Variant Vulnerabilities for Intel Discovered - four of them critical

"News has just started spreading that researchers have sighted another eight Spectre like vulnerabilities in Intel processors, all resemble Spectre, four of them are critical. The new vulnerabilities are grouped and named as Spectre-ng. The newly discovered vulnerabilities would make it really easy to exploit a host from a simple VM."

"While technical details are missing, the attack scenarios resemble close to what the Spectre vulnerabilities are."

http://www.guru3d.com/news-story/eight-new-spectre-variant-vulnerabilities-for-intel-discovered-four-of-them-critical.html

https://www.heise.de/ct/artikel/Super-GAU-fuer-Intel-Weitere-Spectre-Luecken-im-Anflug-4039134.html


Big Vulnerability hits 7-Zip file archiver

"If you use, you can and should download v18.05 of the popular 7-Zip file archiver. The free to use WinZip replacement has a very critical vulnerability for which all it needed was a specially prepped RAR file.

This has been addressed with the release of has been fixed with v18.05, I am highlighting this new v18.05 release this much as this is a pretty bad one as it allows remote execution, based on just a RAR file. The security researcher (landave.io) who discovered the vulnerability informed the developer of 7-Zip on the 6th of March this year. It has patched with the release of 7-Zip 18.05, which not only fixes the vulnerability but also adds ASLR security measures."

http://www.guru3d.com/news-story/big-vulnerability-hits-7-zip-file-archiver-gets-patched-download-v18-05.html

https://landave.io/2018/05/7-zip-from-uninitialized-memory-to-remote-code-execution/

May 3, 2018

Getting Started with Elasticsearch, Kibana, X-Pack and SSL/TLS

Introduction Elasticsearch

Why Elasticsearch? "Elasticsearch is a Near Realtime (NRT) search platform." [1]

Elasticsearch stores only JSON Object (Document). A JSON Object is built up by name and value pairs. Value can be one of the following data types:

  • a string
  • a number
  • an object (JSON object)
  • an array
  • a boolean
  • null

Elasticsearch supports more data types, than standard JSON, such as date and geo-point. [2]

Elasticsearch is accessed primarly with JSON over HTTP.

Several of the same documents type are mapped to Types. Which can be thought of as Tables in a RDBM. Different Types are stored in an Indices (plural of Index) which can be thought of a Database.

MySQL => Databases => Tables => Columns/Rows
Elasticsearch => Indices => Types => Documents with Properties

Searching and querying takes the format of: http://localhost:9200/[index]/[type]/[id], i.e. GET localhost:9200/accounts/person/1

An Index can potentially grow and be very large, to help that, Elasticsearch splits Index to multiple Shards. Both Index and Shard are stored in a server Node.

"Sharding is important for two primary reasons:

  • It allows you to horizontally split/scale your content volume
  • It allows you to distribute and parallelize operations across shards (potentially on multiple nodes) thus increasing performance/throughput"

"... Elasticsearch allows you to make one or more copies of your index’s shards into what are called replica shards, or replicas for short."

"Replication is important for two primary reasons:

  • It provides high availability in case a shard/node fails. For this reason, it is important to note that a replica shard is never allocated on the same node as the original/primary shard that it was copied from.
  • It allows you to scale out your search volume/throughput since searches can be executed on all replicas in parallel."

Multiple Nodes forms a Cluster. When you first start Elasticsearch, you start a Node in a Cluster called "elasticsearch", i.e. you have created a Cluster with one Node.

Reference

Elasticsearch

Download

$ wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-6.2.4.tar.gz
$ wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-6.2.4.tar.gz.sha512
$ shasum -a 512 -c elasticsearch-6.2.4.tar.gz.sha512 
elasticsearch-6.2.4.tar.gz: OK

ZIP Installation

$ tar -xzf elasticsearch-6.2.4.tar.gz
$ cd elasticsearch-6.2.4/ 

Run Interactively

$ bin/elasticsearch

Test

$ curl http://localhost:9200/
{
  "name" : "hCDxdzG",
  "cluster_name" : "elasticsearch",
  "cluster_uuid" : "npmGFI2nRcmXke0YLW9tXQ",
  "version" : {
    "number" : "6.2.4",
    "build_hash" : "ccec39f",
    "build_date" : "2018-04-12T20:37:28.497551Z",
    "build_snapshot" : false,
    "lucene_version" : "7.2.1",
    "minimum_wire_compatibility_version" : "5.6.0",
    "minimum_index_compatibility_version" : "5.0.0"
  },
  "tagline" : "You Know, for Search"
}

Or open browser 'http://localhost:9200/'.

Reference

Kibana

Download

$ wget https://artifacts.elastic.co/downloads/kibana/kibana-6.2.4-linux-x86_64.tar.gz
$ wget https://artifacts.elastic.co/downloads/kibana/kibana-6.2.4-linux-x86_64.tar.gz.sha512
$ shasum -a 512 -c kibana-6.2.4-linux-x86_64.tar.gz.sha512 
kibana-6.2.4-linux-x86_64.tar.gz: OK

ZIP Installation

$ tar -xzf kibana-6.2.4-linux-x86_64.tar.gz
$ cd kibana-6.2.4-linux-x86_64/ 

Run Interactively

$ bin/kibana

Test

Or open browser 'http://localhost:5601/'.

Reference

X-Pack

"X-Pack is an Elastic Stack extension that bundles security (*), alerting, monitoring, reporting, and graph capabilities into one easy-to-install package."

(*) Authentication, Authorization and Audit Log.

Without X-Pack, Elasticsearch is wide open and everyone can read everything.

Download

$ wget https://artifacts.elastic.co/downloads/packs/x-pack/x-pack-6.2.4.zip
$ wget https://artifacts.elastic.co/downloads/packs/x-pack/x-pack-6.2.4.zip.sha512
$ shasum -a 512 -c x-pack-6.2.4.zip.sha512
x-pack-6.2.4.zip: OK

X-Pack Elasticsearch

Installation

$ bin/elasticsearch-plugin install [x-pack|file:///path/to/file/x-pack-6.2.4.zip]
$ bin/elasticsearch-plugin install file:///home/magnus/bin/x-pack-6.2.4.zip
-> Downloading file:///home/magnus/bin/x-pack-6.2.4.zip
[=================================================] 100%   
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@     WARNING: plugin requires additional permissions     @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
* java.io.FilePermission \\.\pipe\* read,write
* java.lang.RuntimePermission accessClassInPackage.com.sun.activation.registries
* java.lang.RuntimePermission getClassLoader
* java.lang.RuntimePermission setContextClassLoader
* java.lang.RuntimePermission setFactory
* java.net.SocketPermission * connect,accept,resolve
* java.security.SecurityPermission createPolicy.JavaPolicy
* java.security.SecurityPermission getPolicy
* java.security.SecurityPermission putProviderProperty.BC
* java.security.SecurityPermission setPolicy
* java.util.PropertyPermission * read,write
See http://docs.oracle.com/javase/8/docs/technotes/guides/security/permissions.html
for descriptions of what these permissions allow and the associated risks.

Continue with installation? [y/N]y
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@        WARNING: plugin forks a native controller        @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
This plugin launches a native controller that is not subject to the Java
security manager nor to system call filters.

Continue with installation? [y/N]y
Elasticsearch keystore is required by plugin [x-pack-security], creating...
-> Installed x-pack with: x-pack-monitoring,x-pack-ml,x-pack-logstash,x-pack-graph,x-pack-core,x-pack-upgrade,x-pack-deprecation,x-pack-security,x-pack-watcher

Then restart elasticsearch and continue with changing admin passwords.

$ bin/x-pack/setup-passwords [auto|interactive]
$ bin/x-pack/setup-passwords auto
Initiating the setup of passwords for reserved users elastic,kibana,logstash_system.
The passwords will be randomly generated and printed to the console.
Please confirm that you would like to continue [y/N]y

Changed password for user kibana
PASSWORD kibana = PFUPZoLlTdIqECtoS0Qs

Changed password for user logstash_system
PASSWORD logstash_system = sw9XNc2fDskZstgiHdaJ

Changed password for user elastic
PASSWORD elastic = 8fAYzzJ2ZlGxdynE2zqf

Reference

X-Pack Kibana

Installation

$ bin/kibana-plugin install [x-pack|file:///path/to/file/x-pack-6.2.4.zip]
$ bin/kibana-plugin install file:///home/magnus/bin/x-pack-6.2.4.zip
Attempting to transfer from file:///home/magnus/bin/x-pack-6.2.4.zip
Transferring 309419696 bytes....................
Transfer complete
Retrieving metadata from plugin archive
Extracting plugin archive
Extraction complete
Optimizing and caching browser bundles...
Plugin installation complete

Configuration

$ vi config/kibana.yml
...
elasticsearch.username: "kibana"
elasticsearch.password: "PFUPZoLlTdIqECtoS0Qs"
...

Restart Kibana and open browser http://localhost:5601

Username: elastic
Password: 8fAYzzJ2ZlGxdynE2zqf 

Using Kibana

Open http://localhost:5601 in your web browser and select DevTools. Now we will use examples from

https://www.elastic.co/pdf/getting-started-webinar-dev-console-commands.pdf

SSL/TLS Elasticsearch

Encrypting HTTP Client Communications: https://www.elastic.co/guide/en/elasticsearch/reference/6.2/configuring-tls.html#tls-http

Create a root, intermediate and localhost certificate according to http://magnus-k-karlsson.blogspot.se/2016/09/openssl-certificate-authority-ca.html

Server Certificate:

  • /home/magnus/bin/ca/intermediate/certs/localhost.cert.pem
  • /home/magnus/bin/ca/intermediate/private/localhost.key.pem-NOPWD

Server Certificate Chain:

  • /home/magnus/bin/ca/intermediate/certs/intermediate.cert.pem
  • /home/magnus/bin/ca/certs/ca.cert.pem

Elasticsearch do not have a seperate settings for server certificate chain, so you need to add the server certificate chain to the server certificate pem file.

$ cp localhost.cert.pem localhost.cert.pem+ca-chain.cert.pem
$ cat intermediate.cert.pem >> localhost.cert.pem+ca-chain.cert.pem
$ cat ca.cert.pem >> localhost.cert.pem+ca-chain.cert.pem
xpack.security.http.ssl.enabled: true
xpack.security.http.ssl.key:  certs/localhost.key.pem-NOPWD
xpack.security.http.ssl.certificate: certs/localhost.cert.pem+ca-chain.cert.pem

A note about settings 'xpack.security.http.ssl.certificate_authorities', which one might think is server certificate chain, but is NOT. It is for client certificate authentication and is the trusted client certificate CA that are allowed to login. To enable two way SSL you also need to set 'xpack.ssl.client_authentication: required'.

Elasticsearch also supports PKCS#12 format, to use it.

$ cp intermediate.cert.pem ca-chain.cert.pem
$ cat ca.cert.pem >> ca-chain.cert.pem
openssl pkcs12 -export -out localhost.p12 -inkey localhost.key.pem-NOPWD -in localhost.cert.pem -certfile ca-chain.cert.pem
xpack.security.http.ssl.enabled: true
xpack.security.http.ssl.keystore.path: certs/localhost.p12

Created elasticsearch keystore in /home/magnus/bin/elasticsearch-6.2.4/config

$ bin/elasticsearch-keystore create

Enter value for xpack.security.http.ssl.keystore.secure_password:

$ bin/elasticsearch-keystore add xpack.security.http.ssl.keystore.secure_password

This setups transport crypto (HTTPS) and if you want client certificate authentication also, you need to set the truststore property. But using PKCS#12 format for client certificate CA is not a smooth way, specially when client certificate have a different CA than the server certificate. So I would recommend using the PEM settings.

To setup transport crypto for the internal traffic inside elasticsearch nodes, see Encrypting Communications Between Nodes in a Cluster.

To verify your settings you can either open 'localhost:9200' in a web browser and or use 'openssl s_client', to fully verify your SSL/TLS settings.

$ openssl s_client -connect localhost:9200 -showcerts

NOTE When enable SSL/TLS is HTTP disabled.

SSL/TLS Hardening Elasticsearch

The only secure SSL protocol version is TLSv1.2

xpack.ssl.supported_protocols: TLSv1.2

To hardening you cipher suite you need to install Java Cryptography Extension (JCE), if you are running OpenJDK it is already installed and if you are running Oracle JDK, you need to install it.

Here we will use OWASP TLS/SSL Cheat Sheet

https://www.owasp.org/index.php/Transport_Layer_Protection_Cheat_Sheet#Rule_-_Only_Support_Strong_Cryptographic_Ciphers

$ openssl ciphers -v "EDH+aRSA+AESGCM:EDH+aRSA+AES:EECDH+aRSA+AESGCM:EECDH+aRSA+AES:-SHA:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:RSA+AESGCM:RSA+AES+SHA256:RSA+AES+SHA:DES-CBC3-SHA:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA"
DHE-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=DH       Au=RSA  Enc=AESGCM(256) Mac=AEAD
DHE-RSA-AES128-GCM-SHA256 TLSv1.2 Kx=DH       Au=RSA  Enc=AESGCM(128) Mac=AEAD
DHE-RSA-AES256-SHA256   TLSv1.2 Kx=DH       Au=RSA  Enc=AES(256)  Mac=SHA256
DHE-RSA-AES128-SHA256   TLSv1.2 Kx=DH       Au=RSA  Enc=AES(128)  Mac=SHA256
ECDHE-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH     Au=RSA  Enc=AESGCM(256) Mac=AEAD

ECDHE-RSA-AES256-SHA384 TLSv1.2 Kx=ECDH     Au=RSA  Enc=AES(256)  Mac=SHA384
ECDHE-RSA-AES128-SHA256 TLSv1.2 Kx=ECDH     Au=RSA  Enc=AES(128)  Mac=SHA256
ECDHE-RSA-AES256-SHA    SSLv3 Kx=ECDH     Au=RSA  Enc=AES(256)  Mac=SHA1
ECDHE-RSA-AES128-SHA    SSLv3 Kx=ECDH     Au=RSA  Enc=AES(128)  Mac=SHA1
AES256-GCM-SHA384       TLSv1.2 Kx=RSA      Au=RSA  Enc=AESGCM(256) Mac=AEAD
AES128-GCM-SHA256       TLSv1.2 Kx=RSA      Au=RSA  Enc=AESGCM(128) Mac=AEAD
AES256-SHA256           TLSv1.2 Kx=RSA      Au=RSA  Enc=AES(256)  Mac=SHA256
AES128-SHA256           TLSv1.2 Kx=RSA      Au=RSA  Enc=AES(128)  Mac=SHA256
AES256-SHA              SSLv3 Kx=RSA      Au=RSA  Enc=AES(256)  Mac=SHA1
AES128-SHA              SSLv3 Kx=RSA      Au=RSA  Enc=AES(128)  Mac=SHA1
DES-CBC3-SHA            SSLv3 Kx=RSA      Au=RSA  Enc=3DES(168) Mac=SHA1
DHE-RSA-AES256-SHA      SSLv3 Kx=DH       Au=RSA  Enc=AES(256)  Mac=SHA1
DHE-RSA-AES128-SHA      SSLv3 Kx=DH       Au=RSA  Enc=AES(128)  Mac=SHA1

Then we filter out:

  • only TLSv1.2 ciphers
  • only encryption AESGCM
  • only key exchange DH or ECDH

Which leaves us with only these four ciphers

DHE-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=DH       Au=RSA  Enc=AESGCM(256) Mac=AEAD
DHE-RSA-AES128-GCM-SHA256 TLSv1.2 Kx=DH       Au=RSA  Enc=AESGCM(128) Mac=AEAD

ECDHE-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH     Au=RSA  Enc=AESGCM(256) Mac=AEAD
ECDHE-RSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH     Au=RSA  Enc=AESGCM(128) Mac=AEAD

Now we need to map these ciphers to Java: https://docs.oracle.com/javase/8/docs/technotes/guides/security/SunProviders.html#SunJSSEProvider

TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
TLS_DHE_RSA_WITH_AES_128_GCM_SHA256

TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
xpack.ssl.cipher_suites: TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256

Then restart and verify

$ openssl s_client -connect localhost:9200 -showcerts
...
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : DHE-RSA-AES256-GCM-SHA384
...

Reference

SSL/TLS Kibana

When setting up SSL/TLS for Kibana you first need to set https in the URL to Elasticsearch.

elasticsearch.url: "https://localhost:9200"

Then we need to add a truststore in Kibanan, so it trust the Elasticsearch SSL/TLS. A few notes about the certificate management in Kibana:

  • All files needs to be inside kibana directory, due to X-Pack Java Security Manager.
  • You need to use absulte path, compared with elasticsearch.
elasticsearch.ssl.certificateAuthorities: [ "/home/magnus/bin/kibana-6.2.4-linux-x86_64/config/certs/intermediate.cert.pem", "/home/magnus/bin/kibana-6.2.4-linux-x86_64/config/certs/ca.cert.pem" ]

Then restart Kibana and test that you can access http://localhost:5601.

Username: elastic
Password: 8fAYzzJ2ZlGxdynE2zqf 

When OK, then lets continue with setting up SSL/TLS for Kibana.

server.ssl.enabled: true
server.ssl.certificate: /home/magnus/bin/kibana-6.2.4-linux-x86_64/config/certs/localhost+ca-chain.cert.pem
server.ssl.key: /home/magnus/bin/kibana-6.2.4-linux-x86_64/config/certs/localhost.key.pem-NOPWD

And finally test it: https://localhost:5601/

Reference