Thursday, April 25, 2013

WiFi QR-code generator


Usage preview

With current (Android) mobiles it is possible to add a WiFi network by scanning a QR-code. Barcode Scanner by ZXing Team is one of the apps recognizing the WiFi QR-codes. Other QR-code generators online (that support WiFi-QR) generate the QR-code server side, which means the data, including the password, is sent over the internet. Since I wasn't comfortable with this, I have created an open source Javascript alternative.

http://qistoph.github.io/WiFiQR/

Use this generator to generate a QR-code without having your precious WiFi information sent over the internet. Such a QR-code might, for example, be useful to allow your guests to easily add your WiFi network to their phone when visiting.

Usage
Select the encryption used in your network (WEP, WPA or none).
Enter your SSID.
Enter the password for the network.
If the SSID is hidden, set the visibility button to 'Hidden'.
Click 'Generate' and/or 'Print'

Friday, April 12, 2013

PKCS#7 and OpenSSL

In an earlier post I have tried to demonstrate how to verify a PKCS#7 manually, because I wanted to know how such messages work and why it would be secure. Judging by the reactions that were posted I think a lot  you are actually more interested in a proper way of decrypting and verifying PKCS#7 messages with OpenSSL. Therefore I will show you how to encrypt, decrypt, sign and verify PKCS#7 messages, with OpenSSL in a more proper way.

NOTE: to actually use these methods securely could, and probably does, require decent understanding of data encryption!

If you are in doubt, feel free to leave a message and I'll try to be of assistance.

Setup

Before we can start encrypting and signing messages we'll require some keys and certificates. Let's create a self-signed certificate based on a new key with the subject "PKCS#7 example".

openssl req -x509 -nodes -newkey rsa:1024 -keyout keyfile.key -out certificate.cer -subj "/CN=PKCS#7 example"

This should result in the creation of two new files:
  • certificate.cer - containing a PEM-encoded X.509 certificate
  • keyfile.key - containing a PEM-encoded (RSA) private key
To view ASN.1 encoded files, both, DER and PEM, with more ease I have created two aliases in my terminal:

alias oad='openssl asn1parse -inform der -in'
alias oap='openssl asn1parse -inform pem -in'

oad is used to "OpenSSL ASN.1 dump DER"
oap is used to "OpenSSL ASN.1 dump PEM"

e.g.
oap certificate.cer
    0:d=0  hl=4 l= 512 cons: SEQUENCE
    4:d=1  hl=4 l= 361 cons: SEQUENCE
    8:d=2  hl=2 l=   3 cons: cont [ 0 ]
   10:d=3  hl=2 l=   1 prim: INTEGER           :02
   13:d=2  hl=2 l=   9 prim: INTEGER           :D28124BDCEECCCCC
   24:d=2  hl=2 l=  13 cons: SEQUENCE
   26:d=3  hl=2 l=   9 prim: OBJECT            :sha1WithRSAEncryption
   37:d=3  hl=2 l=   0 prim: NULL
   39:d=2  hl=2 l=  25 cons: SEQUENCE
   41:d=3  hl=2 l=  23 cons: SET
   43:d=4  hl=2 l=  21 cons: SEQUENCE
   45:d=5  hl=2 l=   3 prim: OBJECT            :commonName
   50:d=5  hl=2 l=  14 prim: UTF8STRING        :PKCS#7 example
   66:d=2  hl=2 l=  30 cons: SEQUENCE
   68:d=3  hl=2 l=  13 prim: UTCTIME           :130412203318Z
   83:d=3  hl=2 l=  13 prim: UTCTIME           :130512203318Z
   98:d=2  hl=2 l=  25 cons: SEQUENCE
  100:d=3  hl=2 l=  23 cons: SET
  102:d=4  hl=2 l=  21 cons: SEQUENCE
  104:d=5  hl=2 l=   3 prim: OBJECT            :commonName
  109:d=5  hl=2 l=  14 prim: UTF8STRING        :PKCS#7 example
  125:d=2  hl=3 l= 159 cons: SEQUENCE
  128:d=3  hl=2 l=  13 cons: SEQUENCE
  130:d=4  hl=2 l=   9 prim: OBJECT            :rsaEncryption
  141:d=4  hl=2 l=   0 prim: NULL
  143:d=3  hl=3 l= 141 prim: BIT STRING
  287:d=2  hl=2 l=  80 cons: cont [ 3 ]
  289:d=3  hl=2 l=  78 cons: SEQUENCE
  291:d=4  hl=2 l=  29 cons: SEQUENCE
  293:d=5  hl=2 l=   3 prim: OBJECT            :X509v3 Subject Key Identifier
  298:d=5  hl=2 l=  22 prim: OCTET STRING      [HEX DUMP]:0414B2ED2165623A8E3E5EB9652E781590C314EFC5B6
  322:d=4  hl=2 l=  31 cons: SEQUENCE
  324:d=5  hl=2 l=   3 prim: OBJECT            :X509v3 Authority Key Identifier
  329:d=5  hl=2 l=  24 prim: OCTET STRING      [HEX DUMP]:30168014B2ED2165623A8E3E5EB9652E781590C314EFC5B6
  355:d=4  hl=2 l=  12 cons: SEQUENCE
  357:d=5  hl=2 l=   3 prim: OBJECT            :X509v3 Basic Constraints
  362:d=5  hl=2 l=   5 prim: OCTET STRING      [HEX DUMP]:30030101FF
  369:d=1  hl=2 l=  13 cons: SEQUENCE
  371:d=2  hl=2 l=   9 prim: OBJECT            :sha1WithRSAEncryption
  382:d=2  hl=2 l=   0 prim: NULL
  384:d=1  hl=3 l= 129 prim: BIT STRING


Encryption

Encryption can be used to make a message only available to the target receiver and prevents eavesdropping. The message is encrypted with a public key, quiet often stored in a certificate. Because of the mathematical properties of the private and public key, the message can only be read with possession of the private key. In this example I'll show you how to encrypt a message that is only readable when decrypted with the private key created before. To encrypt a message we'll be using the newly created certificate we're using the smime command of OpenSSL. Have a look at the help for all the available options of this command (openssl smime --help).

Store the message we'll be encrypting in a file:
echo "This message won't be readable until decrypted again." > plain-original.txt

Then encrypt this message using the key from the certificate.cer created earlier. If the outform isn't specified the default output format is smime, for now I'll use pem:
openssl smime -encrypt -in plain-original.txt -outform pem -out encrypted.p7 certificate.cer

Verifiy the encrypted.p7 contains content that looks a bit like this:
oap encrypted.p7
-----BEGIN PKCS7-----
MIIBPAYJKoZIhvcNAQcDoIIBLTCCASkCAQAxgcAwgb0CAQAwJjAZMRcwFQYDVQQD
DA5QS0NTIzcgZXhhbXBsZQIJANKBJL3O7MzMMA0GCSqGSIb3DQEBAQUABIGAh/s9
JYTGgh46iAH95n2UQNuDNQWgG01akoVuj0KR9ChbRQuQPSas+p+eMK1ipyCPnLtv
7Mhcjsf0yPGkFod39LxiOhcepe2vRcwYxTaGgBHk7VMS2ilZwKZMYki1gxjCKe6b
BlK3kVGx5dA0YEEhIWNPbL4IZhn+Orx2HrL8mgAwYQYJKoZIhvcNAQcBMBoGCCqG
SIb3DQMCMA4CAgCgBAjzFuJU6hSmNoA49ZNTG5kYKkttlsot8ak+jaDPAbrwobFL
5BPmv4MyRtmBaRiHToCJMK+DfigMi3smVE2FeYC3YGQ=
-----END PKCS7-----

Decryption

A PKCS#7 encrypted message can be recognized by the PKCS#7 content type, which is pkcs7-envelopedData:
oap encrypted.p7
    0:d=0  hl=4 l= 316 cons: SEQUENCE
    4:d=1  hl=2 l=   9 prim: OBJECT            :pkcs7-envelopedData
   15:d=1  hl=4 l= 301 cons: cont [ 0 ]
   19:d=2  hl=4 l= 297 cons: SEQUENCE
   23:d=3  hl=2 l=   1 prim: INTEGER           :00
   26:d=3  hl=3 l= 192 cons: SET
   29:d=4  hl=3 l= 189 cons: SEQUENCE
   32:d=5  hl=2 l=   1 prim: INTEGER           :00
   35:d=5  hl=2 l=  38 cons: SEQUENCE
   37:d=6  hl=2 l=  25 cons: SEQUENCE
   39:d=7  hl=2 l=  23 cons: SET
   41:d=8  hl=2 l=  21 cons: SEQUENCE
   43:d=9  hl=2 l=   3 prim: OBJECT            :commonName
   48:d=9  hl=2 l=  14 prim: UTF8STRING        :PKCS#7 example
   64:d=6  hl=2 l=   9 prim: INTEGER           :D28124BDCEECCCCC
   75:d=5  hl=2 l=  13 cons: SEQUENCE
   77:d=6  hl=2 l=   9 prim: OBJECT            :rsaEncryption
   88:d=6  hl=2 l=   0 prim: NULL
   90:d=5  hl=3 l= 128 prim: OCTET STRING      [HEX DUMP]:7A7782B34EC3C63ABAD847DC4C028AFB8C1072CB1A43154A7CBFB2CB5B31874FB0D5EF8607AE442762595CDB6C15BD6C0373F0CD21B25396AF457F3699BC87C09B7F2552BB7A9A03EE7EBD3FF8961A00D161BED2CF3214E491D18A26B3992DD1129AC2F4FC860A3E1A84C6F2115E788F6436EAD35A257FAD50D871D34E50F335
  221:d=3  hl=2 l=  97 cons: SEQUENCE
  223:d=4  hl=2 l=   9 prim: OBJECT            :pkcs7-data
  234:d=4  hl=2 l=  26 cons: SEQUENCE
  236:d=5  hl=2 l=   8 prim: OBJECT            :rc2-cbc
  246:d=5  hl=2 l=  14 cons: SEQUENCE
  248:d=6  hl=2 l=   2 prim: INTEGER           :A0
  252:d=6  hl=2 l=   8 prim: OCTET STRING      [HEX DUMP]:A05AF334241D3C3C
  262:d=4  hl=2 l=  56 prim: cont [ 0 ]

To decrypt a PKCS#7 envelopedData message we need access to the private key. In this example I will use the private key we've stored in the keyfile.key before. The OpenSSL smime command in used again:
openssl smime -decrypt -inform pem -in encrypted.p7 -inkey keyfile.key
This message won't be readable until decrypted again.

Signing

Signing a message in PKCS#7 format is almost as simple as encrypting it. Signing is done with the private key. This allows anyone who has access to the public key to verify that the message was signed by the owner of the matching private key and is used to proof the origin of a message.

Create a message to be signed:
echo "This message could only have been sent by me." > unsigned-original.txt

In this example I'm adding the -nodetach option. This option tells OpenSSL to include the original message in the PKCS#7 structure too. Besides the private key the certificate is also required for signing. This is used by OpenSSL to include a reference to the certificate in the signed message (an Issuer - SerialNumber combination, which should be unique). This reference enables the receiver to find the matching certificate, and thus public key. The command I'm using is as follows:
openssl smime -sign -nodetach -in unsigned-original.txt -out signed.p7 -outform pem -inkey keyfile.key -signer certificate.cer

The content is again PEM-encoded and can be parsed with asn1parse:
cat signed.p7
-----BEGIN PKCS7-----
MIIEFgYJKoZIhvcNAQcCoIIEBzCCBAMCAQExCzAJBgUrDgMCGgUAMD4GCSqGSIb3
DQEHAaAxBC9UaGlzIG1lc3NhZ2UgY291bGQgb25seSBoYXZlIGJlZW4gc2VudCBi
eSBtZS4NCqCCAgQwggIAMIIBaaADAgECAgkA0oEkvc7szMwwDQYJKoZIhvcNAQEF
BQAwGTEXMBUGA1UEAwwOUEtDUyM3IGV4YW1wbGUwHhcNMTMwNDEyMjAzMzE4WhcN
MTMwNTEyMjAzMzE4WjAZMRcwFQYDVQQDDA5QS0NTIzcgZXhhbXBsZTCBnzANBgkq
hkiG9w0BAQEFAAOBjQAwgYkCgYEAnvFUnLFlzYScwPXCTBdp+e3pBAV/wFc10gq2
bKCcHg6WgWrnW39HJxaYdn6Edzt8ipdTvX2Kl6iQXtjAIs8oI7YBdqxZMknddM1M
mvbe0HVYPoF0lIWiLLIySYeV6GC2X0eYyWE1FLs1qJsRSrHA8iHlDH4gngGMu71d
WCEbXg8CAwEAAaNQME4wHQYDVR0OBBYEFLLtIWViOo4+XrllLngVkMMU78W2MB8G
A1UdIwQYMBaAFLLtIWViOo4+XrllLngVkMMU78W2MAwGA1UdEwQFMAMBAf8wDQYJ
KoZIhvcNAQEFBQADgYEAG1PiV0P2iZhh88juujpr/BrlMm64BlX1hrsLyyNR6e85
iBC4kFJNndkFiCFz31EAJkzoMIUdgn07cENk2KAjf3BIrgBaeY6mp94s6lpRcfK7
lEsfbyADOQqszCuzadMHZd44XReMaf43Kw/WYwVmsHpBDpzgAwH1sxtSKcHnFmox
ggGnMIIBowIBATAmMBkxFzAVBgNVBAMMDlBLQ1MjNyBleGFtcGxlAgkA0oEkvc7s
zMwwCQYFKw4DAhoFAKCB2DAYBgkqhkiG9w0BCQMxCwYJKoZIhvcNAQcBMBwGCSqG
SIb3DQEJBTEPFw0xMzA0MTIyMTExMTVaMCMGCSqGSIb3DQEJBDEWBBS0KhYhWkxR
nvCUyavULWwbRXaF1jB5BgkqhkiG9w0BCQ8xbDBqMAsGCWCGSAFlAwQBKjALBglg
hkgBZQMEARYwCwYJYIZIAWUDBAECMAoGCCqGSIb3DQMHMA4GCCqGSIb3DQMCAgIA
gDANBggqhkiG9w0DAgIBQDAHBgUrDgMCBzANBggqhkiG9w0DAgIBKDANBgkqhkiG
9w0BAQEFAASBgHq2NEUYm1csunOIOlekNBPW12EWMU3lTK+phxPtKZl+y2233NLN
TWaLUaRF7ePjapr71IYlrLfse9Kv8xl8o2QU+XMhj1p2I6Ng0lt3VfwjgJ5isidk
GM/suaYFITr4PxGlhZKEtoYQh4BOr0r0+iy6aFJGKAhn4slB6qdhn025
-----END PKCS7-----

oap signed.p7
    0:d=0  hl=4 l=1046 cons: SEQUENCE
    4:d=1  hl=2 l=   9 prim: OBJECT            :pkcs7-signedData
   15:d=1  hl=4 l=1031 cons: cont [ 0 ]
   19:d=2  hl=4 l=1027 cons: SEQUENCE
   23:d=3  hl=2 l=   1 prim: INTEGER           :01
   26:d=3  hl=2 l=  11 cons: SET
   28:d=4  hl=2 l=   9 cons: SEQUENCE
   30:d=5  hl=2 l=   5 prim: OBJECT            :sha1
   37:d=5  hl=2 l=   0 prim: NULL
   39:d=3  hl=2 l=  62 cons: SEQUENCE
   41:d=4  hl=2 l=   9 prim: OBJECT            :pkcs7-data
   52:d=4  hl=2 l=  49 cons: cont [ 0 ]
   54:d=5  hl=2 l=  47 prim: OCTET STRING      :This message could only have been sent by me.

  103:d=3  hl=4 l= 516 cons: cont [ 0 ]
  107:d=4  hl=4 l= 512 cons: SEQUENCE
  111:d=5  hl=4 l= 361 cons: SEQUENCE
  115:d=6  hl=2 l=   3 cons: cont [ 0 ]
  117:d=7  hl=2 l=   1 prim: INTEGER           :02
  120:d=6  hl=2 l=   9 prim: INTEGER           :D28124BDCEECCCCC
  131:d=6  hl=2 l=  13 cons: SEQUENCE
  133:d=7  hl=2 l=   9 prim: OBJECT            :sha1WithRSAEncryption
  144:d=7  hl=2 l=   0 prim: NULL
  146:d=6  hl=2 l=  25 cons: SEQUENCE
  148:d=7  hl=2 l=  23 cons: SET
  150:d=8  hl=2 l=  21 cons: SEQUENCE
  152:d=9  hl=2 l=   3 prim: OBJECT            :commonName
  157:d=9  hl=2 l=  14 prim: UTF8STRING        :PKCS#7 example
  173:d=6  hl=2 l=  30 cons: SEQUENCE
  175:d=7  hl=2 l=  13 prim: UTCTIME           :130412203318Z
  190:d=7  hl=2 l=  13 prim: UTCTIME           :130512203318Z
  205:d=6  hl=2 l=  25 cons: SEQUENCE
  207:d=7  hl=2 l=  23 cons: SET
  209:d=8  hl=2 l=  21 cons: SEQUENCE
  211:d=9  hl=2 l=   3 prim: OBJECT            :commonName
  216:d=9  hl=2 l=  14 prim: UTF8STRING        :PKCS#7 example
  232:d=6  hl=3 l= 159 cons: SEQUENCE
  235:d=7  hl=2 l=  13 cons: SEQUENCE
  237:d=8  hl=2 l=   9 prim: OBJECT            :rsaEncryption
  248:d=8  hl=2 l=   0 prim: NULL
  250:d=7  hl=3 l= 141 prim: BIT STRING
  394:d=6  hl=2 l=  80 cons: cont [ 3 ]
  396:d=7  hl=2 l=  78 cons: SEQUENCE
  398:d=8  hl=2 l=  29 cons: SEQUENCE
  400:d=9  hl=2 l=   3 prim: OBJECT            :X509v3 Subject Key Identifier
  405:d=9  hl=2 l=  22 prim: OCTET STRING      [HEX DUMP]:0414B2ED2165623A8E3E5EB9652E781590C314EFC5B6
  429:d=8  hl=2 l=  31 cons: SEQUENCE
  431:d=9  hl=2 l=   3 prim: OBJECT            :X509v3 Authority Key Identifier
  436:d=9  hl=2 l=  24 prim: OCTET STRING      [HEX DUMP]:30168014B2ED2165623A8E3E5EB9652E781590C314EFC5B6
  462:d=8  hl=2 l=  12 cons: SEQUENCE
  464:d=9  hl=2 l=   3 prim: OBJECT            :X509v3 Basic Constraints
  469:d=9  hl=2 l=   5 prim: OCTET STRING      [HEX DUMP]:30030101FF
  476:d=5  hl=2 l=  13 cons: SEQUENCE
  478:d=6  hl=2 l=   9 prim: OBJECT            :sha1WithRSAEncryption
  489:d=6  hl=2 l=   0 prim: NULL
  491:d=5  hl=3 l= 129 prim: BIT STRING
  623:d=3  hl=4 l= 423 cons: SET
  627:d=4  hl=4 l= 419 cons: SEQUENCE
  631:d=5  hl=2 l=   1 prim: INTEGER           :01
  634:d=5  hl=2 l=  38 cons: SEQUENCE
  636:d=6  hl=2 l=  25 cons: SEQUENCE
  638:d=7  hl=2 l=  23 cons: SET
  640:d=8  hl=2 l=  21 cons: SEQUENCE
  642:d=9  hl=2 l=   3 prim: OBJECT            :commonName
  647:d=9  hl=2 l=  14 prim: UTF8STRING        :PKCS#7 example
  663:d=6  hl=2 l=   9 prim: INTEGER           :D28124BDCEECCCCC
  674:d=5  hl=2 l=   9 cons: SEQUENCE
  676:d=6  hl=2 l=   5 prim: OBJECT            :sha1
  683:d=6  hl=2 l=   0 prim: NULL
  685:d=5  hl=3 l= 216 cons: cont [ 0 ]
  688:d=6  hl=2 l=  24 cons: SEQUENCE
  690:d=7  hl=2 l=   9 prim: OBJECT            :contentType
  701:d=7  hl=2 l=  11 cons: SET
  703:d=8  hl=2 l=   9 prim: OBJECT            :pkcs7-data
  714:d=6  hl=2 l=  28 cons: SEQUENCE
  716:d=7  hl=2 l=   9 prim: OBJECT            :signingTime
  727:d=7  hl=2 l=  15 cons: SET
  729:d=8  hl=2 l=  13 prim: UTCTIME           :130412211115Z
  744:d=6  hl=2 l=  35 cons: SEQUENCE
  746:d=7  hl=2 l=   9 prim: OBJECT            :messageDigest
  757:d=7  hl=2 l=  22 cons: SET
  759:d=8  hl=2 l=  20 prim: OCTET STRING      [HEX DUMP]:B42A16215A4C519EF094C9ABD42D6C1B457685D6
  781:d=6  hl=2 l= 121 cons: SEQUENCE
  783:d=7  hl=2 l=   9 prim: OBJECT            :S/MIME Capabilities
  794:d=7  hl=2 l= 108 cons: SET
  796:d=8  hl=2 l= 106 cons: SEQUENCE
  798:d=9  hl=2 l=  11 cons: SEQUENCE
  800:d=10 hl=2 l=   9 prim: OBJECT            :aes-256-cbc
  811:d=9  hl=2 l=  11 cons: SEQUENCE
  813:d=10 hl=2 l=   9 prim: OBJECT            :aes-192-cbc
  824:d=9  hl=2 l=  11 cons: SEQUENCE
  826:d=10 hl=2 l=   9 prim: OBJECT            :aes-128-cbc
  837:d=9  hl=2 l=  10 cons: SEQUENCE
  839:d=10 hl=2 l=   8 prim: OBJECT            :des-ede3-cbc
  849:d=9  hl=2 l=  14 cons: SEQUENCE
  851:d=10 hl=2 l=   8 prim: OBJECT            :rc2-cbc
  861:d=10 hl=2 l=   2 prim: INTEGER           :80
  865:d=9  hl=2 l=  13 cons: SEQUENCE
  867:d=10 hl=2 l=   8 prim: OBJECT            :rc2-cbc
  877:d=10 hl=2 l=   1 prim: INTEGER           :40
  880:d=9  hl=2 l=   7 cons: SEQUENCE
  882:d=10 hl=2 l=   5 prim: OBJECT            :des-cbc
  889:d=9  hl=2 l=  13 cons: SEQUENCE
  891:d=10 hl=2 l=   8 prim: OBJECT            :rc2-cbc
  901:d=10 hl=2 l=   1 prim: INTEGER           :28
  904:d=5  hl=2 l=  13 cons: SEQUENCE
  906:d=6  hl=2 l=   9 prim: OBJECT            :rsaEncryption
  917:d=6  hl=2 l=   0 prim: NULL
  919:d=5  hl=3 l= 128 prim: OCTET STRING      [HEX DUMP]:7AB63445189B572CBA73883A57A43413D6D76116314DE54CAFA98713ED29997ECB6DB7DCD2CD4D668B51A445EDE3E36A9AFBD48625ACB7EC7BD2AFF3197CA36414F973218F5A7623A360D25B7755FC23809E62B2276418CFECB9A605213AF83F11A5859284B6861087804EAF4AF4FA2CBA685246280867E2C941EAA7619F4DB9

Verification

Verifying a PKCS#7 message is done to verify the authenticity of the message and to make sure it was sent by someone who has access to the private key. OpenSSL also tries to verify the certificate included in the message (or supplied on the commandline in some cases). Because I'm using a self signed certificate in this example the verification of the certificate will fail; because it's not signed by a trusted party.

openssl smime -verify -in signed.p7 -inform pem
Verification failure
2675740:error:21075075:PKCS7 routines:PKCS7_verify:certificate verify error:pk7_smime.c:342:Verify error:self signed certificate

To overcome this we could add the -noverify option. This might look a bit weird (openssl verify -noverify...), but the message is still verified against the certificate. It's just the verification of the certificate itself that is skipped. Nevertheless this option should of course only be used when the full implications are understood!
openssl smime -verify -in signed.p7 -inform pem -noverify
This message could only have been sent by me.
Verification successful

Summary

OpenSSL is a verify powerful tool that can be a bit hard to operate. Depending on your (security) requirements some of the examples provided might be more suitable to your situation than others. Using these commands, or tailored versions, for troubleshooting or in testing environments should be OK. If however you plan on using these in a production environment, please, and don't take this lightly, consult someone with decent understanding of data encryption and key management!

openssl smime -encrypt -in plain-original.txt -outform pem -out encrypted.p7 certificate.cer

openssl smime -decrypt -inform pem -in encrypted.p7 -inkey keyfile.key

openssl smime -sign -nodetach -in unsigned-original.txt -out signed.p7 -outform pem -inkey keyfile.key -signer certificate.cer

openssl smime -verify -in signed.p7 -inform pem