# Module Signing with a YubiKey Neo

**URL:** <https://forum.inductiveautomation.com/t/module-signing-with-a-yubikey-neo/12079>\
**Category:** 3rd Party Modules\
**Created:** [August 29, 2016, 6:02pm UTC](https://forum.inductiveautomation.com/t/module-signing-with-a-yubikey-neo/12079 "2016-08-29T18:02:41Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [August 29, 2016, 6:02pm UTC](https://forum.inductiveautomation.com/t/module-signing-with-a-yubikey-neo/12079/1 "2016-08-29T18:02:41Z")

</div>

I tackled this topic in the past few days because I’ve been unhappy with having my code signing private key exposed regularly on my development workstation. Yes, I might be paranoid, but why beg for trouble?  
Anyways, I kept a log of the necessary steps, and thought I’d document them publicly.  
[ol][li]Buy a smartcard and interface, or dongle that emulates one. It must be able to hold an RSA key pair, and be supported by the [OpenSC](https://github.com/OpenSC) project. There may be other tools that make this work, but this is the path recommended for the YubiKey Neo that I have kicking around.[/li]  
[li]Buy an appropriate Java code signing certificate, suitable for use with Ignition’s [code signing tool](https://docs.inductiveautomation.com:8443/display/SE/Module+Signing). I bought mine from [DigiCert](https://www.digicert.com/). Many other providers are available. The following could be adapted to a self-signed certificate, but if you are comfortable doing that, you should be comfortable modifying these instructions.[/li]  
[li]Extract your private key from your keystore. All of the instructions I’ve seen for setting up java code signing for Java start with creating a key pair and certificate signing request in a new keystore. However, Java’s keytool does not provide any means to export the private key. This needs to be in a format acceptable to your smartcard’s management tool, typically PEM. With a bit of research, and inspiration from [Dr. Herong Yang](http://www.herongyang.com/crypto/Migrating_Keys_keytool_to_OpenSSL.html), I scripted the following:[code]import sys

if len(sys.argv)\<5:  
print “”“Usage:  
%s keystore storepass alias aliaspass”"" % sys.argv[0]  
exit()

from [java.io](http://java.io) import FileInputStream  
from java.security import KeyStore  
from java.util import Base64

ks = KeyStore.getInstance(“jks”)  
ks.load(FileInputStream(sys.argv[1]), sys.argv[2]);  
key = ks.getKey(sys.argv[3], sys.argv[4]);

print “-----BEGIN %s PRIVATE KEY-----” % key.algorithm  
print Base64.getMimeEncoder().encodeToString(key.encoded)  
print “-----END %s PRIVATE KEY-----” % key.algorithm[/code]I saved the output of mine to autopros-code-signer.key. Be sure to thoroughly destroy this file when you’re done with it, as this format is completely unprotected.[/li]  
[li]Extract your certificate from your certificate chain, unless your smartcard can hold the entire chain. Mine cannot. OpenSSL can read the PKCS7 file you received from your certificate authority and print out the PEM format certificates within it.[code]$ openssl pkcs7 -in automation\_professionals\_llc.p7b -print\_certs  
subject=/C=US/ST=Georgia/L=Fairburn/O=Automation Professionals, LLC/CN=Automation Professionals, LLC  
issuer=/C=US/O=DigiCert Inc/OU=[www.digicert.com/CN=DigiCert](http://www.digicert.com/CN=DigiCert) SHA2 Assured ID Code Signing CA  
-----BEGIN CERTIFICATE-----  
MIIFRjCCBC6gAwIBAgIQBC4XZ6EMC3Rt3NDxHkDILzANBgkqhkiG9w0BAQsFADBy  
… trimmed …  
NZ6qrkwjTVZeWLHQoawP4QXf7ITC0lAh7mdi7jJde9bEbOc8FvS5CEKtIZXaGLv/  
hVOTeXeSUsMHcg==  
-----END CERTIFICATE-----

… trimmed the rest of the certificate chain …[/code]You only want to extract the certificate that has you as the subject, and only the lines from “-----BEGIN CERTIFICATE-----” to “-----END CERTIFICATE-----”. I cut and pasted mine into a file named autopros-code-signer.pem.[/li]  
[li]Install smartcard software. For me, that was yubikey-neo-manager, opensc, and ykpersonalize. I use Gentoo Linux, so installations instructions wouldn’t be much use (and are likely to vary). But it seems these are all easily installed on typical Windows and Linux platforms. The Yubikey PIV Manager application can do much of the following in a GUI.[/li]  
[li]Configure your smartcard/dongle for certificate mode, if needed. For the YubiKey Neo, it comes out of the box configured in One-Time-Password mode, with an info report like so:`$ ykinfo -a
serial: 3647291
serial_hex: 37a73b
serial_modhex: eilien
version: 3.4.3
touch_level: 1797
programming_sequence: 1
slot1_status: 1
slot2_status: 0
vendor_id: 1050
product_id: 114`. It needs to be in “CCID” mode. I chose the CCID-only mode, which is a one-way conversion for the standard tool:[code]$ ykpersonalize -m1  
Firmware version 3.4.3 Touch level 1797 Program sequence 1

The USB mode will be set to: 0x1

Commit? (y/n) [n]: y  
WARNING: This tool will not be able to switch back from the selected mode, really commit? (y/n) [n]: y  
[/code]After removing and re-inserting, the mode change takes effect. Empty, you see:[code]$ pkcs11-tool -L  
Available slots:  
Slot 0 (0x0): Yubico Yubikey NEO CCID 00 00  
token label : PIV\_II (PIV Card Holder pin)  
token manufacturer : piv\_II  
token model : PKCS#15 emulated  
token flags : rng, login required, PIN initialized, token initialized  
hardware version : 0.0  
firmware version : 0.0  
serial num : 00000000

$ yubico-piv-tool -a status  
CHUID: No data available  
CCC: No data available  
PIN tries left: 3[/code][/li][li]Install your key and certificate with the vendor-specific tools and verify:[code]$ yubico-piv-tool -s 9a -a import-key -i autopros-code-signer.key  
Successfully imported a new private key.

$ yubico-piv-tool -s 9a -a import-certificate -i autopros-code-signer.pem  
Successfully imported a new certificate.

$ yubico-piv-tool -a status  
CHUID: No data available  
CCC: No data available  
Slot 9a:  
Algorithm: RSA2048  
Subject DN: C=US, ST=Georgia, L=Fairburn, O=Automation Professionals, LLC, CN=Automation Professionals, LLC  
Issuer DN: C=US, O=DigiCert Inc, [OU=www.digicert.com](http://OU=www.digicert.com), CN=DigiCert SHA2 Assured ID Code Signing CA  
Fingerprint: 3c2ef8bbb52cf79408b170c558652be21c22b250b92dbcbe70a604a74a155466  
Not Before: Apr 12 00:00:00 2016 GMT  
Not After: Apr 17 12:00:00 2018 GMT  
PIN tries left: 3[/code]This would be the appropriate point to change your smartcard’s PIN, too. 🙂[/li]  
[li]Create an OpenSC configuration for Java to use with your smartcard. Place it in your workspace along with your PKCS7 file from your Certificate Authority. Then you can use Java’s keytool to verify that you can access the key in your smartcard:[code]$ cat pkcs11.cfg  
name = OpenSC  
library = /usr/lib64/opensc-pkcs11.so  
description = OpenSC PKCS11 Provider

$ keytool -keystore NONE -storetype PKCS11 -providerClass sun.security.pkcs11.SunPKCS11 -providerArg pkcs11.cfg -list  
Enter keystore password: {pin}

Keystore type: PKCS11  
Keystore provider: SunPKCS11-OpenSC

Your keystore contains 1 entry

Certificate for PIV Authentication, PrivateKeyEntry,  
Certificate fingerprint (SHA1): 0C:3A:3D:8E:10:3A:F9:F7:90:DE:CF:EF:71:70:90:C8:DC:97:54:E7[/code]Note the alias your smartcard assigned to your key. For YubiKeys under OpenSC, slot 9a is given alias “Certificate for PIV Authentication”. You need to supply this to the module signing tool, as shown below.[/li]  
[li]Configure your module project to call the module signer tool with the “-pkcs11-cfg=” parameter instead of the “-keystore=” parameter, and give it the name of your OpenSC configuration file. Use the alias your smartcard shows instead of your original keystore’s alias. Supply the smartcard’s pin as both the keystore password and the alias password. I still use the Ant build system, so I call the module signer with this script:[code]

 [/code][/li][/ol]I currently have a local patch in my module-signer project that adds this pkcs11 mode of operation, but you can expect to see it in the public project soon. :slight\_smile:

---

<div class="post-metadata">

**Author:** ![Kevin.Herron](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kevin.herron/32/7259_2.png) [@Kevin.Herron](https://forum.inductiveautomation.com/u/Kevin.Herron)\
**Post date:** [August 30, 2016, 2:21pm UTC](https://forum.inductiveautomation.com/t/module-signing-with-a-yubikey-neo/12079/2 "2016-08-30T14:21:10Z")

</div>

Phil’s patch has been merged into the module signing util ![:thumb_left:](https://us1.discourse-cdn.com/inductiveautomation/original/1X/e26afb081ddde6df016df6ee49159cf56aaca688.gif ":thumb\_left:")
