Cryptographic API Functions/en
Reference: MD5Stream inherits from: HashStream
Inhaltsverzeichnis
Hashing[Bearbeiten]
All hash algorithms are accessed the same way, by either sending one of the convenient utility messages to a hash-stream-class, or by instantiating a hash stream and sending it the data to be hashed (byte-wise or block-wise).
The utility messages are easier to use, but require the hhash data to be already present in a byte- or character collection (i.e. in memory), which may be inefficient or impossible, if big chunks are to be hashed.
The instance messages allow for streams of unknown length to be hashed, to preinitialize the parameters and to fetch/reset the hash value during the operation.
Available hash classes are (among many others): MD5Stream
, SHA1Stream
, SHA256Stream
, SHA512Stream
, RipeMD160Stream
, SipHashStream
, WhirlpoolStream
etc.
Open a class browser or evaluate "HashStream allSubclasses inspect
" to see them all.
eXept may provide additional hash classes upon request.
Class-Side Utility Protocol[Bearbeiten]
- HashStreamClass hashValueOf: aStringOrByteArray
- Returns the hash value as a byte vector (the length of the vector depends on the algorithm).
- Example:
MD5Stream hashValueOf:
'hello world' => #[94 182 59 187 224 30 238 208 147 203 34 187 143 90 205 195]SHA1Stream hashValueOf:
'hello world' => #[42 174 108 53 201 79 207 180 21 219 233 95 64 139 156 233 30 232 70 237]SHA256Stream hashValueOf:
'hello world' => #[185 77 39 185 147 77 62 8 165 46 82 215 218 125 171 250 196 132 239 227 122 83 128 238 144 136 247 172 226 239 205 233]
- HashStreamClass hashValueHexString: aStringOrByteArray
- Returns the hash value as a hex string.
- Example:
MD5Stream hashValueHexString:
'hello world' => '5eb63bbbe01eeed093cb22bb8f5acdc3'SHA1Stream hashValueHexString:
'hello world' => '2aae6c35c94fcfb415dbe95f408b9ce91ee846ed'SHA256Stream hashValueHexString:
'hello world' => 'b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9'
- HashStreamClass hashValueOfFile: aFilename
- Returns the hash of a file's contents.
- Example:
MD5Stream hashValueOfFile:
'Makefile'SHA256Stream hashValueOfFile:
'Makefile'(SHA256Stream hashValueOfFile:
'Makefile') hexPrintString(SHA256Stream hashValueOfFile:
'Makefile') hexPrintString asLowercase
Instance Protocol[Bearbeiten]
More fine control is available by instantiating a hash-stream and sending it the data. First, create an instance:
myHashStream := HashStreamClass new
.
then send it the bytes to be hashed with the usual stream messages:
myHashStream nextPutAll: stringOrByteCollection myHashStream nextPut: characterOrSingleByteValue
and finally ask the stream for its current (running) hashValue with:
myHashStream hashValue
Thus, the above utility in the MD5Stream is equivalent to:
myStream := MD5Stream new. myStream nextPutAll:'hello world'. hashBytes := myStream hashValue. hashHexString := myStream hashValue hexPrintString asLowercase.
Encryption & Decryption[Bearbeiten]
This is done by instantiating a cipher, defining the block-chaining mode and streaming data blocks to it. The way to setup the cipher may differ between the individual algorithms: some require a key only, others require more parameters (e.g. an init vector).
Notice that the raw cipher instance operates in ecb mode, which is very insecure. Send one of the mode messages to define the block chaining mode (ofb, cfg, ctr, etc.)
Common Cipher Class Protocol[Bearbeiten]
All Cipher classes can be asked for the keySize and blockSize:
- aCipherClass keySize
- the length of the key (in bytes). If it supports multiple keySizes, the preferred or typical size is returned.
- aCipherClass keySizes
- a collection of supported key sizes. If the cipher supports only one keySize, the collection will contain only one element.
- aCipherClass blockSize
- blocks of data are encrypted/decrypted in multiples of the blockSize.
- Depending on the block chaining mode, data may have to be passed to the cipher in multiples of that size.
- aCipherClass blockSizes
- a collection of supported block sizes.
Common BlockCipher Instance Protocol[Bearbeiten]
- aCipher ofb
- returns an object which implements the output feedback mode on top of the cipher. ::Supports the same stream protocol as the cipher. The message length is not required to be a multiple of the cipher's block size.
- aCipher ctr
- similar for counter mode. The message length is not required to be a multiple of the cipher's block size.
- aCipher cbc
- similar for cipher block chaining mode. The message length must be a multiple of the cipher's block size.
- aCipher cfb
- similar for cipher feedback mode. The message length is not required to be a multiple of the cipher's block size.
DES Cipher[Bearbeiten]
In basic ECB mode (attention: insecure!!):
key := #[12 34 56 78 90 12 34 56]. cipher := DesCipher new. cipher key: key. encrypted := cipher encrypt: 'hello world'. ... decrypted := cipher decrypt: encrypted.
in CFB mode:
key := #[12 34 56 78 90 12 34 56]. cipher := DesCipher new cfb. cipher key: key. encrypted := cipher encrypt: 'hello world'. ... decrypted := cipher decrypt: encrypted.
Tea Cipher[Bearbeiten]
In basic ECB mode (attention: insecure!):
key := '00112233445566778899aabbccddeeff'. cipher := TeaCipher new. cipher key: key. encrypted := cipher encrypt: 'hello world'. ... decrypted := cipher decrypt: encrypted.
In OFB (output feedback block mode) mode:
... cipher := TeaCipher new ofb. cipher key: key. cipher initialVector:#[1 2 3 4 5 6 7 8]. ...
Others...[Bearbeiten]
Many more ciphers are available; open a browser or evaluate "Cipher allSubclasses inspect
" in a workspace.
Certificate Handling[Bearbeiten]
Reading from a PEM File[Bearbeiten]
Use fromPemStream:
to convert a PEM file.
cert := X509Certificate fromPemStream:('file.pem' asFilename readStream)
This method can also read a string in case the PEM is already available:
cert := X509Certificate fromPemStream:' -----BEGIN CERTIFICATE----- MIIHBTCCBO2gAwIBAgIBATANBgkqhkiG9w0BAQsFADBUMQswCQYDVQQGEwJERTEa MBgGA1UEChMRRXhlcHQgU29mdHdhcmUgQUcxEDAOBgNVBAsTB1Rlc3RpbmcxFzAV ... vthHg54SuEay1ge+PvggvOqvMB4laWakbA== -----END CERTIFICATE----- '.
Writing as a PEM File[Bearbeiten]
'filename.pem' asFilename writeStream nextPutAll:cert asSignedPemString; close.
Writing as a DER Encoded File[Bearbeiten]
'filename.crt' asFilename writeStream binary; nextPutAll:caCert asSignedDerBytes; close.
or more convenient:
'filename.crt' asFilename contents:(caCert asSignedDerBytes)
Creation[Bearbeiten]
To create a self-signed certificate,
cert := X509CaCertificate new subjectNameString:'C=DE, O=MyCompany, CN=Test'; issuerNameString:'C=DE, O= MyCompany, CN=Test-CA'; serialNumber:4711; signatureAlgorithmNameString:#sha256WithRSAEncryption; startValidity:Timestamp now; endValidity:(Date today + 365) asTimestamp; key:(RSASecretCryptKey generateKeyLength:4096 publicExponent:65537 rng:RandomGenerator new); signSelf
Supported algorithm names (by time this document was written) are:
- #sha1WithRSAEncryption, #sha224WithRSAEncryption, #sha256WithRSAEncryption,
- #md2WithRSAEncryption, #md5WithRSAEncryption, #sha384WithRSAEncryption,
- #sha512WithRSAEncryption.
Be aware that most of them are considered insecure nowadays - they are only to be used to support older protocols. If in doubt, ask your security staff.
Signing[Bearbeiten]
To sign a new certificate, given a root CA certificate:
rootCA signCertificate:cert.
Validation[Bearbeiten]
** more to be documented **
Key Exchange[Bearbeiten]
** to be documented **
SSL Streams[Bearbeiten]
** to be documented **