Skip to content

ID encryption

Sam Tingleff edited this page Dec 17, 2019 · 2 revisions

Background

DigiTrust IDs are encrypted using 2048 bit RSA keys. Keys are expected to cycle approximately each month via an API which is tbd as of September 2019.

At launch, the public key exists in a javascript resource on the DigiTrust CDN. Members will receive the version 1 (which is announced in the js as version 4) private key via a secure channel. The expectation is that decryption is a strictly server side operation and that members will never expose private keys in the browser.

The following code samples are provided to aid in decryption.

Keys

Public

-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvTFcroWQM88aTRtXeEzo
73h1zVGxrH2TcrDvs/o0vujpOBZFiDuTrnXZJhucady+GG1Evc4TrJMg4fsaqfMv
bAH3jUoaWFvZ93TwOaNQiq5Lg0Ub9OX/m4J0l/rioVP3ZemNKt2o5EOSIQ/iyIFX
vJKmGa+BLTCsXuXYiuG/cCrNJ+8ktJxU/htA/1aZpHqrb2F+RuxdQkLzVUXsPzMe
tDGxpHOa933dWxG+dknhq/hC3nlCi5PDfhRurV/avlnE9oYSKQSRNltFiPWfhFu1
hVaWgEhFpqglkvVcMwyp3Y6PzwXXzojliYqJXA9NQRxSSoAM16GM9oJB6sdkttI5
jwIDAQAB
-----END PUBLIC KEY-----

Private

-----BEGIN PRIVATE KEY-----
MIIEpAIBAAKCAQEAvTFcroWQM88aTRtXeEzo73h1zVGxrH2TcrDvs/o0vujpOBZF
iDuTrnXZJhucady+GG1Evc4TrJMg4fsaqfMvbAH3jUoaWFvZ93TwOaNQiq5Lg0Ub
9OX/m4J0l/rioVP3ZemNKt2o5EOSIQ/iyIFXvJKmGa+BLTCsXuXYiuG/cCrNJ+8k
tJxU/htA/1aZpHqrb2F+RuxdQkLzVUXsPzMetDGxpHOa933dWxG+dknhq/hC3nlC
i5PDfhRurV/avlnE9oYSKQSRNltFiPWfhFu1hVaWgEhFpqglkvVcMwyp3Y6PzwXX
zojliYqJXA9NQRxSSoAM16GM9oJB6sdkttI5jwIDAQABAoIBAGptkUiv4/3xHEeS
APOwuDy2U/aLZVq2TbLwK/ff4bofhcrCZJ0Nfrdenihc0fGPdvSAy3HGsrSbE51s
R4ShQ+ULejnmHMnl6cjV5KlX4OASynHu95odpFvT2EkCnmjItlyDNKGPjgnSpSqq
KBZJBJUVHhFG9HD6d4zu2ZDPC4VJ5f2k0Vy7cXwTPnqQGY+SVEGa/DmMC3ffI1cn
bG64PvZgD6dFmEpZQz1fegbntAqC2v9ftlxa0VsTAjTofgzBA31GK0jiV22DOKNn
HzcPG/mWcwsJJXBP7dnn0yU0bA+7n6XLNMK04khC5+i/Dq84/bfmlYXi1TSkDiNZ
TwQG7ckCgYEA8PIsG1oiCOPbFL20k0yhM1mAdwlvap2cRqCVs4JKrYWnfOy7XyY/
LIj/lVmVGYKE4Ctc5U49iAhLWsKgovb6R0LmxqWrm8X7Mi/6nGJ1Xv6D47gqbjVR
AH0XoZixx/3E2DstZQpxDn3033WVKD805gQEDy6tQs63w9Rjd+RbG70CgYEAyQNr
iWNG53RQjnxfxbnHn9/VR8lrVMLBaf5yqPpQn5OUgOWKZKliF+0D4ZZoDzB6iMHp
BB1L6mlxk3Z1uymH//sQMQ54gKv0yqXUgQ70YNclmpmJJF0lIkf/CdGKgGinbPLh
ZSZPUJN2Dc+uPAuXzELmMc4kqPwVmyNJ+Si4+TsCgYEAoa1e+1uXyu9aaqiBKvYY
lSRRl461PI1V9+55hWLASX+Ny73uXQKFEZU8KzNZYSy7jNCMHTJLB6TJK7W9pJyl
hHvX7yPr6zMGQ77+I0HOEFgol/1UO297UyCdYsnbQZ9/HrlW1J4VDuxmDCwSUldX
X6ECOE3R5SphFP7HYAPTPuECgYBWdR4frY+lpaWwY1ZeGRX/caqugbekcU/3YvW2
MFPVDwjkl9X6jdAfMlZlBOglAFjz0VOD7YXlgQzUvDLPGYHhW/8O2oaB8XQMZV8N
U31Q2bjW0grmlRmPsR/E/Vdw+5Jnjd/cPaoHoiU4s4bhVKsps+yGp3+lHye73mXG
wPkuWQKBgQCbWdXJosy3Ru1hZxMEyCLLYF+cJUjw+z+XgM61vRpbh5BOgEQL1U1+
izU7+AO/2JFWYfPh8k5SOSh2qrfp+pbT090+v2B5Cz7HrGvNCVFExNcgTV0H3Gun
zXaFBogKAklHMsDTZbGSzjPaO/kIewusUWTBdlMzPFQsKYqfQKS5OA==
-----END PRIVATE KEY-----

OpenSSL

cat id-encrypted-base64.txt | base64 --decode | openssl rsautl -inkey private.pem -oaep -decrypt

Or on newer versions of openssl

cat id-encrypted-base64.txt | base64 --decode | openssl pkeyutl -decrypt -inkey private.pem -pkeyopt rsa_padding_mode:oaep

Java

Prerequisite

openssl pkcs8 -topk8 -nocrypt -in private.pem -outform DER -out private.der

Encrypted ID

S00AnozlH+Tm2gFspe0B9P2nvxCerq772mVhF5TvtvhXRRuI7wXk3pErcE98eoGmzqRnEbCMa4SjQi0WKa9toq6xxQfMCKhgd5iu7hqpuyWrkDYBt6VPFs/ws0PkHR4XaMGQ5NTdefkn5kuN0/+xxdQYPVU7SupkMA6UTo2PSLFmTKCtgI/DgnvGw/sBIx8qqVTnuo7EWFY53xJwgtLDxn8zNX+LEFKI4i2LvdEYfPXkjZ7GZrmyrJeQ5VQcm9owzM+9CauARGQ5RonPQcIULHlpiEYJU6gPyrHYpPf020pMq7ARPBWjfaZ4MOXmxSvjFzKKIeQnGTsw/Amq8WyIPw==
import java.io.File;
import java.nio.file.Files;
import java.security.Key;
import java.security.KeyFactory;
import java.security.spec.PKCS8EncodedKeySpec;

import javax.crypto.Cipher;

import org.apache.commons.codec.binary.Base64;

public class Playground {

	public static void main(String[] args) throws Exception {
		// openssl genrsa -out private.pem 2048
		// openssl rsa -in private.pem -outform PEM -pubout -out public.pem
		// openssl pkcs8 -topk8 -nocrypt -in private.pem -outform DER -out private.der
		// openssl rsa -in private.pem -pubout -outform DER -out public.der

		Key privKey = readPrivateKey();

		byte[] base64Ciphertext = Files.readAllBytes(new File("id-encrypted-base64.txt").toPath());
		byte[] ciphertext = Base64.decodeBase64(base64Ciphertext);

		Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-1AndMGF1Padding");
		cipher.init(Cipher.DECRYPT_MODE, privKey);
		byte[] plainText = cipher.doFinal(ciphertext);
		System.out.println(new String(plainText));
		byte[] unencoded = Base64.decodeBase64(plainText);
		System.out.println(new BigInteger(unencoded));
	}

	private static Key readPrivateKey() throws Exception {
		byte[] privKeyBytes = Files.readAllBytes(new File("private.der").toPath());
		PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(privKeyBytes);
		KeyFactory kf = KeyFactory.getInstance("RSA");
		Key privKey = kf.generatePrivate(spec);
		return privKey;
	}
}

PHP

<?php
    $pemPrivateKey = '-----BEGIN PRIVATE KEY-----
MIIEpAIBAAKCAQEAvTFcroWQM88aTRtXeEzo73h1zVGxrH2TcrDvs/o0vujpOBZF
iDuTrnXZJhucady+GG1Evc4TrJMg4fsaqfMvbAH3jUoaWFvZ93TwOaNQiq5Lg0Ub
9OX/m4J0l/rioVP3ZemNKt2o5EOSIQ/iyIFXvJKmGa+BLTCsXuXYiuG/cCrNJ+8k
tJxU/htA/1aZpHqrb2F+RuxdQkLzVUXsPzMetDGxpHOa933dWxG+dknhq/hC3nlC
i5PDfhRurV/avlnE9oYSKQSRNltFiPWfhFu1hVaWgEhFpqglkvVcMwyp3Y6PzwXX
zojliYqJXA9NQRxSSoAM16GM9oJB6sdkttI5jwIDAQABAoIBAGptkUiv4/3xHEeS
APOwuDy2U/aLZVq2TbLwK/ff4bofhcrCZJ0Nfrdenihc0fGPdvSAy3HGsrSbE51s
R4ShQ+ULejnmHMnl6cjV5KlX4OASynHu95odpFvT2EkCnmjItlyDNKGPjgnSpSqq
KBZJBJUVHhFG9HD6d4zu2ZDPC4VJ5f2k0Vy7cXwTPnqQGY+SVEGa/DmMC3ffI1cn
bG64PvZgD6dFmEpZQz1fegbntAqC2v9ftlxa0VsTAjTofgzBA31GK0jiV22DOKNn
HzcPG/mWcwsJJXBP7dnn0yU0bA+7n6XLNMK04khC5+i/Dq84/bfmlYXi1TSkDiNZ
TwQG7ckCgYEA8PIsG1oiCOPbFL20k0yhM1mAdwlvap2cRqCVs4JKrYWnfOy7XyY/
LIj/lVmVGYKE4Ctc5U49iAhLWsKgovb6R0LmxqWrm8X7Mi/6nGJ1Xv6D47gqbjVR
AH0XoZixx/3E2DstZQpxDn3033WVKD805gQEDy6tQs63w9Rjd+RbG70CgYEAyQNr
iWNG53RQjnxfxbnHn9/VR8lrVMLBaf5yqPpQn5OUgOWKZKliF+0D4ZZoDzB6iMHp
BB1L6mlxk3Z1uymH//sQMQ54gKv0yqXUgQ70YNclmpmJJF0lIkf/CdGKgGinbPLh
ZSZPUJN2Dc+uPAuXzELmMc4kqPwVmyNJ+Si4+TsCgYEAoa1e+1uXyu9aaqiBKvYY
lSRRl461PI1V9+55hWLASX+Ny73uXQKFEZU8KzNZYSy7jNCMHTJLB6TJK7W9pJyl
hHvX7yPr6zMGQ77+I0HOEFgol/1UO297UyCdYsnbQZ9/HrlW1J4VDuxmDCwSUldX
X6ECOE3R5SphFP7HYAPTPuECgYBWdR4frY+lpaWwY1ZeGRX/caqugbekcU/3YvW2
MFPVDwjkl9X6jdAfMlZlBOglAFjz0VOD7YXlgQzUvDLPGYHhW/8O2oaB8XQMZV8N
U31Q2bjW0grmlRmPsR/E/Vdw+5Jnjd/cPaoHoiU4s4bhVKsps+yGp3+lHye73mXG
wPkuWQKBgQCbWdXJosy3Ru1hZxMEyCLLYF+cJUjw+z+XgM61vRpbh5BOgEQL1U1+
izU7+AO/2JFWYfPh8k5SOSh2qrfp+pbT090+v2B5Cz7HrGvNCVFExNcgTV0H3Gun
zXaFBogKAklHMsDTZbGSzjPaO/kIewusUWTBdlMzPFQsKYqfQKS5OA==
-----END PRIVATE KEY-----';

    $base64Ciphertext =  'S00AnozlH+Tm2gFspe0B9P2nvxCerq772mVhF5TvtvhXRRuI7wXk3pErcE98eoGmzqRnEbCMa4SjQi0WKa9toq6xxQfMCKhgd5iu7hqpuyWrkDYBt6VPFs/ws0PkHR4XaMGQ5NTdefkn5kuN0/+xxdQYPVU7SupkMA6UTo2PSLFmTKCtgI/DgnvGw/sBIx8qqVTnuo7EWFY53xJwgtLDxn8zNX+LEFKI4i2LvdEYfPXkjZ7GZrmyrJeQ5VQcm9owzM+9CauARGQ5RonPQcIULHlpiEYJU6gPyrHYpPf020pMq7ARPBWjfaZ4MOXmxSvjFzKKIeQnGTsw/Amq8WyIPw==';

    $privateKey = openssl_get_privatekey($pemPrivateKey);
    
    $binaryCiphertext = base64_decode($base64Ciphertext);
    $b = openssl_private_decrypt($binaryCiphertext, $decr, $privateKey, OPENSSL_PKCS1_OAEP_PADDING);
    echo "Decrypted ID: " . $decr;
?>
Clone this wiki locally