Cryptographic API Functions/en

Aus expecco Wiki (Version 2.x)
Zur Navigation springen Zur Suche springen

Reference: MD5Stream inherits from: HashStream

Back to Useful API Functions

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 **



Copyright © 2014-2024 eXept Software AG