Sample code for 30+ languages & platforms
SQL Server

Duplicate PHP's openssl_encrypt and openssl_random_pseudo_bytes

See more OpenSSL Examples

Demonstrates how to duplicate PHP's openssl_encrypt function. (https://www.php.net/manual/en/function.openssl-encrypt.php)

Chilkat SQL Server Downloads

SQL Server
-- Important: See this note about string length limitations for strings returned by sp_OAMethod calls.
--
CREATE PROCEDURE ChilkatSample
AS
BEGIN
    DECLARE @hr int
    -- Important: Do not use nvarchar(max).  See the warning about using nvarchar(max).
    DECLARE @sTmp0 nvarchar(4000)
    DECLARE @success int
    SELECT @success = 0

    -- This example requires the Chilkat API to have been previously unlocked.
    -- See Global Unlock Sample for sample code.

    -- Duplicates thw following PHP script:

    -- $text = "This is a test";
    -- $passphrase = "my password";
    -- $iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length("AES-256-CBC"));
    -- $crypted = base64_encode($iv.openssl_encrypt($text, "AES-256-CBC", $passphrase, OPENSSL_RAW_DATA, $iv));
    -- echo $crypted;

    DECLARE @crypt int
    EXEC @hr = sp_OACreate 'Chilkat.Crypt2', @crypt OUT
    IF @hr <> 0
    BEGIN
        PRINT 'Failed to create ActiveX component'
        RETURN
    END

    DECLARE @text nvarchar(4000)
    SELECT @text = 'This is a test'
    DECLARE @passphrase nvarchar(4000)
    SELECT @passphrase = 'my password'

    -- AES is a block cipher.  The IV size for any block cipher is the size of the block, which is defined by the encryption algorithm. 
    -- For AES, the block size is always 16 bytes, regardless of key size (i.e. 128-bits, 192-bits, or 256-bits).
    -- Therefore, generate 16 random bytes for the IV.
    EXEC sp_OASetProperty @crypt, 'EncodingMode', 'base64'
    DECLARE @ivBase64 nvarchar(4000)
    EXEC sp_OAMethod @crypt, 'GenRandomBytesENC', @ivBase64 OUT, 16


    PRINT 'Generated IV = ' + @ivBase64

    -- Because we're doing AES-256-CBC, the key length must be 256-bits (i.e. 32 bytes).
    -- Given that our passphrase is a us-ascii string that can be shorter or longer than 32-bytes, we need to 
    -- somehow transform the passphrase to a 32-byte secret key.  We need to know what openssl_encrypt does.
    -- Here's the answer from the openssl_encrypt documentation:
    -- 
    -- "If the passphrase is shorter than expected, it is silently padded with NUL characters; 
    -- if the passphrase is longer than expected, it is silently truncated."

    -- OK.... so let's pad or shorten to get a 32-byte key.
    DECLARE @bdKey int
    EXEC @hr = sp_OACreate 'Chilkat.BinData', @bdKey OUT

    EXEC sp_OAMethod @bdKey, 'AppendString', @success OUT, @passphrase, 'utf-8'

    DECLARE @sz int
    EXEC sp_OAGetProperty @bdKey, 'NumBytes', @sz OUT
    IF @sz > 32
      BEGIN
        EXEC sp_OAMethod @bdKey, 'RemoveChunk', @success OUT, 32, @sz - 32
      END
    ELSE
      BEGIN
        EXEC sp_OAMethod @bdKey, 'Clear', @success OUT
        EXEC sp_OAMethod @bdKey, 'AppendPadded', @success OUT, @passphrase, 'utf-8', 0, 32
      END

    -- Setup for encryption.
    EXEC sp_OASetProperty @crypt, 'CryptAlgorithm', 'aes'
    EXEC sp_OASetProperty @crypt, 'KeyLength', 256
    EXEC sp_OAMethod @crypt, 'SetEncodedIV', NULL, @ivBase64, 'base64'
    EXEC sp_OAMethod @bdKey, 'GetEncoded', @sTmp0 OUT, 'base64'
    EXEC sp_OAMethod @crypt, 'SetEncodedKey', NULL, @sTmp0, 'base64'

    -- Encrypt and base64 encode.
    DECLARE @cipherText64 nvarchar(4000)
    EXEC sp_OAMethod @crypt, 'EncryptStringENC', @cipherText64 OUT, @text

    -- The PHP code fragment above returns the base64 encoded bytes of the IV and the encrypted text.
    -- So let's do that..
    DECLARE @bd int
    EXEC @hr = sp_OACreate 'Chilkat.BinData', @bd OUT

    EXEC sp_OAMethod @bd, 'AppendEncoded', @success OUT, @ivBase64, 'base64'
    EXEC sp_OAMethod @bd, 'AppendEncoded', @success OUT, @cipherText64, 'base64'
    DECLARE @result nvarchar(4000)
    EXEC sp_OAMethod @bd, 'GetEncoded', @result OUT, 'base64'


    PRINT 'result = ' + @result

    -- Sample output:
    -- dN0vS1O0cWi5BbLAAY+NTf7bs3S27xzPf11RkG47sjs=

    -- Now let's decrypt from the output...

    -- Setup for decryption.
    EXEC sp_OASetProperty @crypt, 'CryptAlgorithm', 'aes'
    EXEC sp_OASetProperty @crypt, 'KeyLength', 256
    EXEC sp_OAMethod @bdKey, 'GetEncoded', @sTmp0 OUT, 'base64'
    EXEC sp_OAMethod @crypt, 'SetEncodedKey', NULL, @sTmp0, 'base64'

    DECLARE @bdResult int
    EXEC @hr = sp_OACreate 'Chilkat.BinData', @bdResult OUT

    EXEC sp_OAMethod @bdResult, 'AppendEncoded', @success OUT, @result, 'base64'
    EXEC sp_OAMethod @bdResult, 'GetEncodedChunk', @sTmp0 OUT, 0, 16, 'base64'
    EXEC sp_OAMethod @crypt, 'SetEncodedIV', NULL, @sTmp0, 'base64'

    -- Remove the IV (first 16 bytes) from the result.
    EXEC sp_OAMethod @bdResult, 'RemoveChunk', @success OUT, 0, 16
    EXEC sp_OAMethod @crypt, 'DecryptBd', @success OUT, @bdResult
    DECLARE @originalText nvarchar(4000)
    EXEC sp_OAMethod @bdResult, 'GetString', @originalText OUT, 'utf-8'


    PRINT 'original text = ' + @originalText

    EXEC @hr = sp_OADestroy @crypt
    EXEC @hr = sp_OADestroy @bdKey
    EXEC @hr = sp_OADestroy @bd
    EXEC @hr = sp_OADestroy @bdResult


END
GO