I gave myself a 1Q2019 target to write proper READMEs for my Github repos. First up is PasswordCrypt. I reproduce the README here.
PasswordCrypt is a library for Pharo Smalltalk to handle passwords salted and hashed by SHA-256/SHA-512. Its primary components are PCPasswordCrypt, PCAuthenticator and PCBasicAuthenticator.
At its core, PCPasswordCrypt provides the following class-side messages:
PCPasswordCrypt sha256crypt: 'secret' withSalt: 'andPepperToo' "'$5$andPepperToo$5p0MWgRMT6l6EA6dYDlFhuQKi.tfCXNd35T99HxbsTD'"
The result is a string in modular crypt format (MFC).
$5 on the left of the
string indicates that the hashing algorithm is SHA-256. For SHA-512, the
On the instance side, PCPasswordCrypt generates the salt randomly if one is not supplied:
PCPasswordCrypt new sha256crypt: 'secret' "'$5$5bUAI5i2$iIdIXcQGhZfNF0HQFG592Ut1I6UtuO/smBPJkKBrRzC'"
PCAuthenticator builds on PCPasswordCrypt to provide username/password management. PCAuthenticator operates as a singleton object to persist its data in the Pharo image across restarts.
| appName auth newUser userToValidate | appName := 'myApp'. "Initialize the authenticator for my application." auth := PCAuthenticator uniqueInstance. auth initializeDatabaseFor: appName. "Add a user." newUser := PCUserCredential appname: appName; username: 'testuser'; password: 'secret'; yourself. auth insertUserCredential: newUser. "Create another user object and validate its password." userToValidate := PCUserCredential appname: appName; username: 'testuser'; password: 'secret'; yourself. auth validateUserCredential: userToValidate "If the passwords match, userToValidate is returned; otherwise, nil is returned."
PCAuthenticatorUI is a simple Spec-based user interface to upsert new usernames/passwords into PCAuthenticator. I wrote it because I simply abhor code snippets containing clear-text passwords, except for demonstration as above. To run PCAuthenticatorUI:
PCAuthenticatorUI new openWithSpec
PCBasicAuthenticator subclasses ZnBasicAuthenticator, the HTTP basic authentication handler in ZincHTTPComponents. It uses PCAuthenticator so that
To install the Pharo code:
Metacello new baseline: 'PasswordCrypt'; repository: 'github://PierceNg/PasswordCrypt/src-st'; load.
PCPasswordCrypt is an FFI to the C library
libshacrypt, built from the
shacrypt512.c in the directory
src-c. To build the C library:
% cd src-c % make
The generated shared library is
libshacrypt.so on Linux and
libshacrypt.dylib on OSX/macOS. It must be placed where the Pharo VM can
find it at run time. My practice is to place the shared library file together
with the Pharo VM's plugins. On macOS, suppose Pharo is installed in
libshacrypt.dylib goes into
sha512crypt.care public domain
I've just added RIPEMD160 to the EVP interface in OpenSSL-Pharo. This post serves as a HOWTO.
OpenSSL's C interface defines RIPEMD160 thusly:
Create LcLibCrypto>>apiEvpRIPEMD160 for it:
Next, create LcEvpRIPEMD160 as a subclass of LcEvpMessageDigest:
Add class-side accessors:
I've migrated OpenSSL-Pharo to Github.
OpenSSL-Pharo now works on Windows. Tested on Windows 10 with a fresh 32-bit Pharo 6.1 zip package downloaded from pharo.org. On Windows this library uses libeay.dll which is bundled with the Pharo VM.
From within Pharo:
The output is an X.509 certificate request, suitable for Let's Encrypt:
Certificate Request: Data: Version: 0 (0x0) Subject: CN=www.samadhiweb.com Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (2048 bit) Modulus: 00:b6:c4:94:dc:83:4c:8f:92:6c:8c:f5:e4:3a:66: b9:6a:90:e8:51:aa:58:da:e4:ea:3a:59:1d:78:96: 14:ab:83:23:2f:20:45:13:70:88:8d:b5:93:8c:18: c5:78:70:c9:b3:8e:e3:f4:66:64:9c:9d:78:b9:dc: 9b:2b:e1:6d:06:d0:b4:6a:83:94:4e:6e:27:dd:12: 7f:79:b2:a1:67:ed:96:bb:29:fd:dd:dd:78:5a:8c: c1:8f:83:8f:f7:c8:b1:52:d2:8b:de:9f:6b:31:9c: 1f:b7:99:34:83:c1:e6:9d:d4:10:59:ff:bd:32:9f: 0a:8c:e2:3b:06:8c:6c:60:24:e2:89:6c:1f:d4:97: c0:e2:77:44:98:31:d8:3f:41:29:e0:ac:ef:56:fb: 7c:a5:55:94:45:51:3d:b6:4e:5b:e7:1b:05:7c:7e: 0b:1d:cc:a3:88:30:7a:98:51:c7:64:cf:d6:29:f1: 16:86:00:b4:72:10:1a:c7:77:16:9d:94:c3:4e:fc: 83:63:e5:d7:09:d6:40:cb:d4:26:7e:3e:c7:e4:64: 7f:7e:1c:af:53:68:24:f5:5c:a6:79:76:2f:cf:29: bf:9c:3d:3e:38:00:5e:9d:a6:f3:92:09:9b:eb:e4: b4:24:ca:a3:d9:ed:6e:ed:bd:06:af:40:fe:7b:f3: 50:c7 Exponent: 65537 (0x10001) Attributes: a0:00 Signature Algorithm: sha256WithRSAEncryption 4a:21:79:18:51:92:2c:d7:cd:ac:f0:f3:bc:6e:53:f3:de:72: 11:56:ce:f3:e1:71:61:a5:8a:cb:95:4f:31:36:1e:65:50:09: 39:71:95:a2:a5:30:c6:fc:36:29:7f:6e:86:1f:2a:52:a9:b8: 55:39:b2:82:b6:67:84:b3:35:2b:be:57:5f:fd:7e:a5:b1:b9: ab:20:65:d7:20:68:97:14:0f:13:30:1d:54:c9:7f:55:0d:58: 0a:14:2d:5b:80:57:a0:6a:73:31:6d:64:52:43:d1:6d:c2:3b: 8f:88:25:9a:6e:50:52:1d:f8:66:c0:d7:ed:85:be:ef:8b:63: 20:c1:48:e4:d2:30:6c:cf:07:27:bb:a7:56:82:8a:7d:c7:fe: 73:29:f1:4a:f4:18:77:0e:56:48:20:41:08:e5:2e:2c:07:67: 16:e3:9c:d5:c3:0e:02:17:c4:11:5c:01:19:20:4b:c9:e2:37: 3b:14:02:90:77:d2:17:1d:62:24:cc:5b:1c:b0:c9:48:71:02: c6:ff:d8:5e:57:30:bb:da:c7:73:4d:40:ed:b2:8f:a1:2c:07: d6:58:22:94:7f:ff:bc:94:38:23:30:fb:0c:51:53:6c:13:f6: dc:92:9e:c8:67:fa:ed:3b:e7:1a:1d:00:6e:5c:f6:c5:27:7c: d7:76:5a:78
I've put up the beginnings of a wrapper for OpenSSL on STH:
Verified on Pharo 6 32- and 64-bit.
My near term goal is to wrap enough libcrypto functionality to implement the client-side of Let's Encrypt.
I meant to put it up on GH, for the ease of forking and PRs, but I couldn't get Iceberg to work, and gitfiletree also failed to load, so STH it is for now.
In the GH repo, C source files are in the src-c directory. Compile with the Makefile there. Move the .so or .dylib file to where the VM can find it.
To load the Smalltalk code, in a Pharo playground:
Run the tests in TestRunner. Provided the Pharo VM can find the shared library, all 12 tests should pass.
This version adds an authentication database that uses in-image persistence, accessed programmatically via the PCAuthenticator uniqueInstance, and a very simple user interface invoked thusly:
Currently PCAuthenticator hardcodes to SHA256. It should be straightforward to make the hashing algorithm pluggable, including from other shared libraries. Hosting on GH makes it easier for forks and PRs.
SQLcipher "is an open source extension to SQLite that provides transparent 256-bit AES encryption of database files." SQLcipher provides the same API as the SQLite Encryption Extension (SEE) by D Richard Hipp, the original developer of SQLite.
I've added SQLcipher/SEE's API to NBSQLite3. By convention, on Unix, SQLcipher produces a shared library named libsqlcipher.so, while the SQLite shared library is named libsqlite3.so. NBSQLite3 switches between the two libraries based on the messages #beSQLcipher and #beSQLite to the NBSQLite3FFI class.
Here's a demonstration code snippet using the keying pragma in SQL:
NBSQLcipherExample class>>examplePragma contains a longer version of the above snippet that includes reopening the encrypted database file without the keying pragma and using the SQLite library.
Tested on Linux Mint. Code updated in Smalltalk Hub. Some refactoring to be expected, because the above snippet using the keying pragma is the only test I've done.
% openssl sha256 libsqlcipher.so SHA256(libsqlcipher.so)= 441cbc559a4f38a018121c6d86caa0cf0fb2c5b2a57c353cc09a4e048ec8ebe8 % ldd libsqlcipher.so linux-gate.so.1 => (0xf77da000) libdl.so.2 => /lib/i386-linux-gnu/libdl.so.2 (0xf7569000) libpthread.so.0 => /lib/i386-linux-gnu/libpthread.so.0 (0xf754d000) libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xf739e000) /lib/ld-linux.so.2 (0xf77dd000)
For good measure, I've also put up a copy of sqlcipher built at the same time. It requires readline.
% openssl sha256 sqlcipher SHA256(sqlcipher)= 4ccb3cf2064d41675406a55c8404a8877a40541dd9830009f4c0e203468e3d7b % ldd sqlcipher linux-gate.so.1 => (0xf770a000) libreadline.so.6 => /lib/i386-linux-gnu/libreadline.so.6 (0xf76a7000) libdl.so.2 => /lib/i386-linux-gnu/libdl.so.2 (0xf76a2000) libpthread.so.0 => /lib/i386-linux-gnu/libpthread.so.0 (0xf7685000) libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xf74d7000) libtinfo.so.5 => /lib/i386-linux-gnu/libtinfo.so.5 (0xf74b5000) /lib/ld-linux.so.2 (0xf770d000)
According to its documentation, on Unix, the Pharo VM's SSL plugin, libSqueakSSL.so, links into OpenSSL libraries dynamically. On my 64bit Ubuntu Trusty machine, OpenSSL is provided by the libssl1.0.0:i386 package.
(By the way, the SSH2 plugin libssh2.so.1.0.1 requires libcrypto too.)
According to packages.ubuntu.com, Trusty's libssl1.0.0 is built from openssl_1.0.1f.orig.tar.gz plus successive upstream patches.
From the OpenBSD developers, LibreSSL is "a version of the TLS/crypto stack forked from OpenSSL in 2014, with goals of modernizing the codebase, improving security, and applying best practice development processes." LibreSSL also comes with libtls, "a new TLS library, designed to make it easier to write foolproof applications".
Let's see how we go about linking libSqueakSSL.so with LibreSSL.
First, download and unpack LibreSSL. Modify the configure script at lines 2287 and 2289 so that LIBCRYPTO_VERSION and LIBSSL_VERSION both say 1:0:0 instead of 35:0:0. Then build LibreSSL:
I'm building on a 64bit OS, hence "-m32". Without "--disable-asm", the build fails. To get the assembler version, which is recommended for serious usage, either set up a 32bit build environment or muck around with autoconf/configure. I suspect the former is easier. :-)
The output files are $SRC/crypto/.libs/libcrypto.so.1.0.0 and $SRC/ssl/.libs/libssl.so.1.0.0. The shared object files have the "1.0.0" suffix because I modified configure above. Alternatively, I could've played around with autoconf, or built the shared objects with the "35.0.0" suffix and sym/hard-link them for the "1.0.0" versions. TIMTOWTDI.
Next, remove the OpenSSL package:
Finally, put the LibreSSL shared object files into the right place. Where this right place is depends on your environment. TIMTOWTDI. I choose to put them in the Pharo VM directory with its other plugins, and arrange to start Pharo with LD_LIBRARY_PATH set appropriately. Going by the output of ldd again, the following is required:
Launch the Pharo 4.0 image and run the Zodiac tests. All tests should pass. Well, except testGetPharoVersion, which looks for a file that apparently no longer exists.
Incidentally, Squeak 5.0-All-in-One's SSL plugin appears to have linked its crypto/SSL libraries in statically, so the only way to upgrade is to build a new plugin.
I bought a Yubikey device and am going to write a Pharo library for it. Meanwhile, I discovered that Richard Prinz has an implementation of RFC 6536 Time-based One Time Passwords for Pharo.
Recently, Adobe was hacked, resulting in, among other breakages, the loss of 130 million passwords. It was revealed that the passwords were encrypted using ECB, electronic cookbook mode, which is a rather poor way of securing passwords.
The MacRumors forum site was also hacked recently. The site runs the vBulletin forumware, which protects passwords using md5crypt.
md5crypt is a password hashing scheme devised by Poul-Henning Kamp in 1995. The hashed password takes the format $1$<salt>$<password-hash>. The hash is designed to be expensive to compute, to slow down attacks. In 2012, Poul-Henning announced that md5crypt was no longer considered safe, in view of advances in computing power.
sha-crypt, from Ulrich Depper, is a public domain implementation of SHA-256/512-based password hashing, which works similarly to md5crypt, using SHA-256/512 and allowing an arbitrary number of rounds through the hashing algorithm.
The following commands build and run sha(256|512)crypt.c as self-test programs:
Next, build shared library:
Move the .so or .dylib file to where your plugins are.
PCPasswordCrypt is a Smalltalk interface to libshacrypt using NativeBoost. It is very simple to use:
Tested on OSX (Mountain Lion) and Linux (Mint 14). The C programs work on FreeBSD, but my self-built FreeBSD Cog VM doesn't have NativeBoost.
NaCl (pronounced "salt") is a new, easy to use high-speed software library for network communication, encryption, decryption, signatures, etc. It uses elliptic curve cryptography. libsodium is a portable fork of NaCl. Crypto-Nacl is a Pharo/Squeak interface to libsodium. It uses FFI. As is, the library should be named liblibsodium.dylib when used with Crypto-Nacl on OSX.
SqueakSSL is a plugin to the platform-native SSL/TLS facility. The plugin is bundled with the Cog VM. Zodiac is an open source, cross-Smalltalk implementation of regular and secure socket streams. Zodiac uses SqueakSSL. Webclient also uses SqueakSSL to support HTTPS.