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);
}
}
I'm dedicated agile security architect/system architect/developer with specialty of open source framework.
May 30, 2018
How to Read PEM PKCS#1 or PKCS#8 Encoded Private Key In Java
How to Read PEM or DER Encoded X509Certificate 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 X509Certificate 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<AccessDescription> 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<DistributionPoint> 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<ObjectIdentifier> 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
"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
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
- [1] https://www.elastic.co/guide/en/elasticsearch/reference/current/_basic_concepts.html
- [2] https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-types.html
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
$ 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
May 2, 2018
How to See the Used Cipher in IE, Chrome and Firefox
https://helpcenter.gsx.com/hc/en-us/articles/207831828-How-to-identify-the-Cipher-used-by-an-
HTTPS-Connection