Friday, August 10, 2018

PowerBuilder 2017 R3 New Feature: Encryption



PowerBuilder 2017 R3 introduces support for encoding and encrypting data, something of particular interest when using REST web services.  We're going to take a look at those new features.


Encoding

The first set of new functions we'll look at are for encoding data.  PowerBuilder has a new CoderObject with three sets of encoding/decoding methods.  All 3 take a UTF8 encoded blob as an argument and return a UTF8 encoded blob.

HexEncode/HexDecode

Hex Encoding converts each byte in the data into it's hexadecimal ASCII value.  That allows the data to be transferred as text rather than binary values.  The decode method is then used to convert the data back into binary format.  As an example, but one that uses plain text, the phrase:
The quick brown fox jumped over the lazy dog
when hex encoded becomes
54686520717569636B2062726F776E20666F78206A756D706564206F76657220746865206C617A7920646F67

Base64Encode/Base64Decode

Base64 Encoding takes each byte of data, breaks it into pieces and then converts the pieces into one of the 64 printable ASCII characters in the Base64 table.  Using our previous example of "The quick brown fox jumped over the lazy dog" we get the following after Base64 encoding:

VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wZWQgb3ZlciB0aGUgbGF6eSBkb2c=

URLEncode/URLDecode

URL encoding deals more with handling special characters found in URLs that can cause problems when the URL is embedded with other data in a transfer format that would end up interpreting those characters incorrectly (e.g. XML).  So, with URL encoding:
https://www.appeon.com/developers/roadmap/encryption-and-decryption-strings-or-binaries.html
becomes:
https%3A%2F%2Fwww.appeon.com%2Fdevelopers%2Froadmap%2Fencryption-and-decryption-strings-or-binaries.html

Symmetric Encryption

Symmetric encryption is useful for encrypting large amounts of data, as it's very fast and can handle large blocks of data (e.g., up to 250 million terabytes).  The issue is that the same key is used for encoding and decoding the data, so you have to find some means of providing the recipient of the message with the key, so it's less secure.
Symmetric encryption
Symmetric encryption (and decryption) is done through a new CyrpterObject, which has two methods of interest here.  Both take UTF8 encoded blobs and return UTF8 encoded blobs.
SymmetricEncrypt ( algorithm, variable, key{, operationmode{, iv{, padding}}})
SymmetricDecrypt ( algorithm, variable, key{, operationmode{, iv{, padding}}})
Where

Asymmetric Encryption

Asymmetric encryption is more secure because the recipient generates a public/private key pair and only transmits the public key to the sender.  The sender uses the recipient's public key to encrypt the data.  However, the public key can't be used to decrypt the data, only the private key can.  Since the recipient hasn't distributed the private key, the data is more secure.



Asymmetric encryption

The problems with asymmetric encryptions are that it is slow and can only process a very limited amount of data.  For example, you can only encrypt up to 117 bytes of data using a 1024-bit RSA key or 245 bytes of data using an 2048-bit RSA key.

In practice, a hybrid encryption model is often used.  The data is encrypted symmetrically using a key that can be shared.  The shared key is then asymmetrically encrypted using the recipient's public key.  The symmetrically encrypted data and the asymmetrically encrypted shared key are then transmitted together.  The recipient uses their private key to asymmetrically decrypt the shared key and then uses the shared key to symmetrically decrypt the data.

As with symmetric encryption, there are two methods on the new CyrpterObject of interest which take UTF-8 blobs as input and return UTF-8 blobs.
AsymmetricEncrypt ( algorithm, variable, pubKey)
AsymmetricDecrypt ( algorithm, variable, privKey)
Where:

  • Algorithm:  RSA or Rabin
  • Variable:  The UTF-8 blob you want to encrypt
  • PubKey:  The recipient's public key
  • PrivKey:  The recipient's private key

However, whereas the key used in symmetric encryption could be generated as a certain length of random characters, there are certain algorithms that must to be used depending on the encryption algorithm to generate a public/private key pair for asymmetric encryption.  There are a number of tools that can be use to generate such key pairs such as open-ssl, puttygen, or the sign tool  (sn.exe) provided as part of the Windows SDK.  PowerBuilder now can as well, using one of the other methods of the new CrytpoObject:
AsymmetricGenerateKey ( algorithm, len, privKey, pubKey)
Where:

  • Algorithm:  RSA, DSA or Rabin
  • Len:  The length of the key desired
  • PrivKey:  A UTF-8 blob passed by reference that receives the private key 
  • PubKey:  A UTF-8 blob passed by reference that receives the public key
The function returns an integer indicating success or failure.

You wouldn't use a key pair generated using DSA for asymmetric encryption.  Instead, you would use it (or a pair generated using RSA or Rabin) for our next topic:  Asymmetric Signing.

Asymmetric Signing

Asymmetric signing serves a different purpose than encryption.  Signing it used to verity (a) the integrity of the data and (b) the source of the data.  During signing, a hash value is calculated for the data.  The sender's private key (not the recipient public key as in asymmetric encryption) is used to encrypt that hash value.  The recipient calculates a hash value for the data they received.  Then they use the sender's public key ( not their private key as in encryption) to decrypt the hash value and compare it with what they calculated.  If they match, they are reasonably confident that the sender is the source of the data and the data wasn't tampered with.

Ss digitalsignature

And once again, we have two methods on the new CrypterObject of interest to us (as well as the AsymmetricGenerateKey method already discussed).

AsymmetricSign ( algorithm, variable, privKey)
AsymmetricVerifySign ( algorithm, variable, pubKey, sign)

Where:
  • Algorithm:  RSADSA or Rabin
  • Variable:  The UTF-8 blob for which you want to verify authorship and integrity
  • PrivKey:  The senders's private key
  • PubKey:  The sender's public key
  • sign:  The UTF-8 blob with the digital signature created by the sender
The AsymmetricSign method returns a UTF-8 blob containing the digital signature to send with the data.  The AsymmetricVerifySign returns 1 or -1 to indicate whether or not the decrypted hash value from the digital signature matches the computed hash value for the data received.

Hashing

Hashing is roughly similar to calculating a checksum on data in order to validate data.  Both are means of taking a large amount of data and reducing it to a much smaller piece of data.  The value calculated before data transmission is then compare with the value afterwards to determine if the data was corrupted during transmission.  There are important difference though in how the two are calculated.

There are three methods on the new CyrpterObject that are used to calculating hash values for data.  Note that unlike encoding or encryption there are no methods for "de-hashing" the value back to the original data.  That can't be done.  The hash is a one-way operation.  

The three methods in question are as follows.  All take a UTF-8 formatted blob as input and return a UTF-8 formatted blog with the calculated hash value.
MD5 (variable)
HMAC ( algorithm, variable, key )
SHA ( algorithm, variable )
Where:
  • Variable:  The UTF-8 blob for which you want to calculate the hash value
  • Algorithm
    •  HMAC:  HMAC-MD5, HMAC-SHA1, HMAC-SHA224, HMAC-SHA256, HMAC-SHA384 or HMAC-SHA512
    • SHA: SHA1, SHA224, SHA256, SHA384, SHA512, SHA3-224, SHA3-256, SHA3-384 or SHA3-512
  • Key:  A UTF-8 formatted blob containing the key to use during the hash calculation

Summary

The new functions provided in the CoderObject and the CyrpterObject give use all of the encoding, encrypting, hashing and signing functionality we can reasonably expect to need for some time.



2 comments:

Pushparaj said...

Hi Bruce,

Can you please share the code which you have used for Appeon Demo. I am trying to do Sign for JWT but I am not getting success on it and help/resources for this new functionality is less. I tried to do the same what you have done but I am getting the results of Blob to String on different characters may be Chinese. I checked your Google Drive PowerBuilder Samples folder but I cannot find it over there.

Thanks in advance.!
Pushparaj

Bruce Armstrong said...

Pushparaj,

The code should be available on CodeXchange on the Appeon Community website.