Using Encrypted Media Files

Encrypted files

Aculab Cloud supports encrypted media and fax files using:

  • Advanced Encryption Standard (AES) cipher algorithm in Cipher Block Chaining (CBC) mode (id: 0, "aescbc")
    This requires a cipher key (128, 192 or 256 bits) and initialisation vector (128 bits).
    Note: multiple encryptions using the same cipher key should use different non-predictable initialisation vectors.

An encrypted media or fax file can be uploaded to Aculab Cloud via the file_write operation of the file management web service.

REST and UAS applications can play and record encrypted files when supplied with the necessary cipher credentials.

Encryption credentials are not stored by Aculab Cloud.

Validation

An encrypted media or fax file must also be validated prior to being used. As the encryption keys are not available when the files are uploaded this stage occurs when the application is running. Any encrypted files that the application wishes to use must be validated. This ensures that the file can be decrypted by Aculab Cloud and is of a supported format (see above).

For a UAS application this validation step is mandatory and must be explicitly called from the application. For .Net UAS applications see IFileManager.FileValidate(), for Java UAS applications see IFileManager.fileValidate() and for Python UAS Applications see UASFileManagement.validate(). Any attempt to play an encrypted media or fax file that hasn't been validated will generate an error.

This validation step will be invoked automatically for REST applications as part of the play or send fax actions.

Tools and Libraries


  • Files compatible with Aculab Cloud can be encrypted using OpenSSL tools or libraries. When using the openssl command line utility the key and initialisation vector must be provided.

    This example demonstrates how to encrypt a file called unencrypted.wav using aes128 with a key of 123456789abc1236789abc1236789abc with the initialisation vector abcdef123defabcdef456defabcdef89 saving the encrypted file in encrypted.wav.

    openssl enc -e -aes128 -K 123456789abc1236789abc1236789abc -iv abcdef123defabcdef456defabcdef89 -in unencrypted.wav -out encrypted.wav

    Files recorded on Aculab Cloud can be decrypted using OpenSSL

    This example demonstrates how to decrypt a file called encrypted.wav using aes128 with a key of 123456789abc1236789abc1236789abc with the initialisation vector abcdef123defabcdef456defabcdef89 saving the unencrypted file in unencrypted.wav.

    openssl enc -d -aes128 -K 123456789abc1236789abc1236789abc -iv abcdef123defabcdef456defabcdef89 -in encrypted.wav -out unencrypted.wav

  • Microsoft's System.Security.Cryptography.Aes class can be used to encrypt files that are compatible with Aculab Cloud or decrypt recordings created by Aculab Cloud.

    This example demonstrates how to encrypt a file called unencrypted.wav using aes128 with a key of 123456789abc1236789abc1236789abc with the initialisation vector abcdef123defabcdef456defabcdef89 saving the encrypted file in encrypted.wav. The AesCipher class performs the encryption/decryption, to be used by both examples:

    using System;
    using System.IO;
    using System.Text;
    using System.Security.Cryptography;
    
    namespace Encrypt
    {
        class AesCipher
        {
            public static byte[][] ExampleKeyIV = new byte[][] {
                new byte[] { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0x12, 0x36,
                             0x78, 0x9a, 0xbc, 0x12, 0x36, 0x78, 0x9a, 0xbc },
                new byte[] { 0xab, 0xcd, 0xef, 0x12, 0x3d, 0xef, 0xab, 0xcd,
                             0xef, 0x45, 0x6d, 0xef, 0xab, 0xcd, 0xef, 0x89 }
            };
    
            public void FileEncryptDecrypt(bool encrypt, string fileIn, string fileOut)
            {
                if (!File.Exists(fileIn))
                {
                    throw new ArgumentException("File " + fileIn + " not found");
                }
    
                byte[] input = File.ReadAllBytes(fileIn);
    
                using (Aes aes = Aes.Create())
                {
                    if (encrypt)
                    {
                        aes.Key = ExampleKeyIV[0];
                        aes.IV = ExampleKeyIV[1];
    
                        byte[] encryptedBytes = Encrypt_Aes(input, aes.Key, aes.IV);
                        File.WriteAllBytes(fileOut, encryptedBytes);
                    }
                    else
                    {
                        aes.Key = ExampleKeyIV[0];
                        aes.IV = ExampleKeyIV[1];
    
                        byte[] decryptedBytes = Decrypt_Aes(input, aes.Key, aes.IV);
                        File.WriteAllBytes(fileOut, decryptedBytes);
                    }
                }
            }
    
            private byte[] Encrypt_Aes(byte[] input, byte[] key, byte[] iv)
            {
                if ((input == null) || (input.Length == 0))
                {
                    throw new ArgumentException("input null or empty");
                }
                if (key == null || key.Length <= 0)
                {
                    throw new ArgumentException("key invalid");
                }
                if (iv == null || iv.Length <= 0)
                {
                    throw new ArgumentException("iv invalid");
                }
    
                byte[] encryptedBytes;
    
                using (Aes aes = Aes.Create())
                {
                    aes.Key = key;
                    aes.IV = iv;
    
                    ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV);
    
                    using (MemoryStream memoryStream = new MemoryStream())
                    {
                        using (CryptoStream cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
                        {
                            using (BinaryWriter writer = new BinaryWriter(cryptoStream))
                            {
                                writer.Write(input);
                            }
                            encryptedBytes = memoryStream.ToArray();
                        }
                    }
                }
    
                return encryptedBytes;
            }
    
            private byte[] Decrypt_Aes(byte[] input, byte[] key, byte[] iv)
            {
                if (input == null || input.Length <= 0)
                {
                    throw new ArgumentException("input null or empty");
                }
                if (key == null || key.Length <= 0)
                {
                    throw new ArgumentException("key invalid");
                }
                if (iv == null || iv.Length <= 0)
                {
                    throw new ArgumentException("iv invalid");
                }
    
                byte[] result;
    
                using (Aes aes = Aes.Create())
                {
                    aes.Key = key;
                    aes.IV = iv;
    
                    ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV);
    
                    using (MemoryStream memoryStream = new MemoryStream(input))
                    {
                        using (CryptoStream cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
                        {
                            using (MemoryStream outputStream = new MemoryStream())
                            {
                                byte[] buffer = new byte[512];
                                int bytesRead;
                                while ((bytesRead = cryptoStream.Read(buffer, 0, buffer.Length)) > 0)
                                {
                                    outputStream.Write(buffer, 0, bytesRead);
                                }
                                result = outputStream.ToArray();
                            }
                        }
                    }
                }
    
                return result;
            }
        }
    }
    

    To encrypt:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace Encrypt
    {
        class Program
        {
            static void Main(string[] args)
            {
                AesCipher aes = new AesCipher();
                aes.FileEncryptDecrypt(true, "unencrypted.wav", "encrypted.wav");
            }
        }
    }
    

    And decrypt:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace Encrypt
    {
        class Program
        {
            static void Main(string[] args)
            {
                AesCipher aes = new AesCipher();
                aes.FileEncryptDecrypt(false, "encrypted.wav", "unencrypted.wav");
            }
        }
    }
    

  • There are a number of Python libraries which can be used to encrypt files which are compatible with Aculab Cloud. These are called cryptography and PyCrypto. They can also be used to decrypt recordings made by Aculab Cloud.

    This example demonstrates how to encrypt a file called unencrypted.wav using aes128 and the M2Crypto library with a key of 123456789abc1236789abc1236789abc with the initialisation vector abcdef123defabcdef456defabcdef89 saving the encrypted file in encrypted.wav.

    import M2Crypto
    from binascii import hexlify, unhexlify
    from cryptography.hazmat.backends import default_backend
    
    key = "123456789abc1236789abc1236789abc"
    iv = "abcdef123defabcdef456defabcdef89"
    infile = 'unencrypted.wav'
    outfile = 'encrypted.wav'
    
    backend = default_backend()
    
    rfile = open(infile, 'rb')
    ofile = open(outfile, 'wb')
    cipher = M2Crypto.EVP.Cipher('aes_128_cbc', unhexlify(key), unhexlify(iv), op=1, padding=1, salt=0)
    bytes_read = rfile.read(8 * 1024)
    out = ''
    while bytes_read:
        out = out + cipher.update(bytes_read)
        bytes_read = rfile.read(8 * 1024)    
    out = out + cipher.final()
    ofile.write(out)
    rfile.close()    
    ofile.close()
    
    

    This example demonstrates how to decrypt a file called encrypted.wav using aes128 with a key of 123456789abc1236789abc1236789abc with the initialisation vector abcdef123defabcdef456defabcdef89 saving the unencrypted file in unencrypted.wav.

    import M2Crypto
    from binascii import hexlify, unhexlify
    from cryptography.hazmat.backends import default_backend
    
    key = "123456789abc1236789abc1236789abc"
    iv = "abcdef123defabcdef456defabcdef89"
    infile = 'encrypted.wav'
    outfile = 'unencrypted.wav'
    
    backend = default_backend()
    
    rfile = open(infile, 'rb')
    ofile = open(outfile, 'wb')
    cipher = M2Crypto.EVP.Cipher('aes_128_cbc', unhexlify(key), unhexlify(iv), op=0, padding=1, salt=0)
    bytes_read = rfile.read(8 * 1024)
    out = ''
    while bytes_read:
        out = out + cipher.update(bytes_read)
        bytes_read = rfile.read(8 * 1024)    
    out = out + cipher.final()
    ofile.write(out)
    rfile.close()    
    ofile.close()
    

  • The javax.crypto library will encrypt files that are compatible with Aculab Cloud or decrypt recordings created by Aculab Cloud. The Cipher should be created with the following transformation AES/CBC/PKCS5Padding.

    This example demonstrates how to encrypt a file called unencrypted.wav using aes128 with a key of 123456789abc1236789abc1236789abc with the initialisation vector abcdef123defabcdef456defabcdef89 saving the encrypted file in encrypted.wav.

    package encrypt;
    
    import javax.crypto.Cipher;
    import javax.crypto.SecretKey;
    import javax.crypto.spec.IvParameterSpec;
    import javax.crypto.spec.SecretKeySpec;
    import javax.xml.bind.DatatypeConverter;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.FileNotFoundException;
     
    public class Encrypt {
    	public static void main(String[] args) throws Exception {
    		String keyarg = "123456789abc1236789abc1236789abc";
    		String ivarg = "abcdef123defabcdef456defabcdef89";
    		String inf = "unencrypted.wav";
    		String outf = "encrypted.wav";
    
    		byte[] ivBytes = DatatypeConverter.parseHexBinary(ivarg);
    		IvParameterSpec iv = new IvParameterSpec(ivBytes);		
    		
    		SecretKey aeskey = new SecretKeySpec(DatatypeConverter.parseHexBinary(keyarg), "AES");
    
    		Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    		cipher.init(Cipher.ENCRYPT_MODE, aeskey, iv);
    
    		FileInputStream reader = null;
    		FileOutputStream writer = null;
    		
    		try {
    			reader = new FileInputStream(inf);
    			writer = new FileOutputStream(outf);
    			byte[] inbuffer = new byte[8 * 1024];
    			byte[] outbuffer;
    			int bytesread = reader.read(inbuffer);			
    			while (bytesread > 0) {
    				outbuffer = cipher.update(inbuffer, 0, bytesread);
    				writer.write(outbuffer);
    				bytesread = reader.read(inbuffer);
    			}
    			writer.write(cipher.doFinal());
    		} catch (FileNotFoundException e) {
    			e.printStackTrace();
    		} catch (IOException e) {
    			e.printStackTrace();
    		} finally {
    			try {
    				if (reader != null) {
    					reader.close();
    				}
    				if (writer != null) {
    					writer.close();
    				}
    			} catch (IOException e) {
    			}
    		}		
    	}
    }
    
    
    

    This example demonstrates how to decrypt a file called encrypted.wav using aes128 with a key of 123456789abc1236789abc1236789abc with the initialisation vector abcdef123defabcdef456defabcdef89 saving the unencrypted file in unencrypted.wav.

    package encrypt;
    
    import javax.crypto.Cipher;
    import javax.crypto.SecretKey;
    import javax.crypto.spec.IvParameterSpec;
    import javax.crypto.spec.SecretKeySpec;
    import javax.xml.bind.DatatypeConverter;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.FileNotFoundException;
     
    public class Encrypt {
    	public static void main(String[] args) throws Exception {
    		String keyarg = "123456789abc1236789abc1236789abc";
    		String ivarg = "abcdef123defabcdef456defabcdef89";
    		String inf = "encrypted.wav";
    		String outf = "unencrypted.wav";
    
    		byte[] ivBytes = DatatypeConverter.parseHexBinary(ivarg);
    		IvParameterSpec iv = new IvParameterSpec(ivBytes);		
    		
    		SecretKey aeskey = new SecretKeySpec(DatatypeConverter.parseHexBinary(keyarg), "AES");
    
    		Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    		cipher.init(Cipher.DECRYPT_MODE, aeskey, iv);
    
    		FileInputStream reader = null;
    		FileOutputStream writer = null;
    		
    		try {
    			reader = new FileInputStream(inf);
    			writer = new FileOutputStream(outf);
    			byte[] inbuffer = new byte[8 * 1024];
    			byte[] outbuffer;
    			int bytesread = reader.read(inbuffer);			
    			while (bytesread > 0) {
    				outbuffer = cipher.update(inbuffer, 0, bytesread);
    				writer.write(outbuffer);
    				bytesread = reader.read(inbuffer);
    			}
    			writer.write(cipher.doFinal());
    		} catch (FileNotFoundException e) {
    			e.printStackTrace();
    		} catch (IOException e) {
    			e.printStackTrace();
    		} finally {
    			try {
    				if (reader != null) {
    					reader.close();
    				}
    				if (writer != null) {
    					writer.close();
    				}
    			} catch (IOException e) {
    			}
    		}		
    	}
    }
    
    

  • The PHP functions openssl_encrypt() and openssl_decrypt() using the methods AES-128-CBC, AES-192-CBC or AES-256-CBC can be used to encrypt or decrypt media files compatible with Aculab Cloud.

    This example demonstrates how to encrypt a file called unencrypted.wav using aes128 with a key of 123456789abc1236789abc1236789abc with the initialisation vector abcdef123defabcdef456defabcdef89 saving the encrypted file in encrypted.wav.

    $method = 'aes-128-cbc';
    $in = 'unencrypted.wav';
    $inhandle = fopen ($in, 'r');
    $inbuffer = fread ($inhandle, filesize ($in));
    file_put_contents ('encrypted.wav', openssl_encrypt ($inbuffer, $method, pack ("H*", "123456789abc1236789abc1236789abc"), true, pack("H*", "abcdef123defabcdef456defabcdef89")));
    

    This example demonstrates how to decrypt a file called encrypted.wav using aes128 with a key of 123456789abc1236789abc1236789abc with the initialisation vector abcdef123defabcdef456defabcdef89 saving the unencrypted file in unencrypted.wav.

    $method = 'aes-128-cbc';
    $in = 'encrypted.wav';
    $inhandle = fopen ($in, 'r');
    $inbuffer = fread ($inhandle, filesize ($in));
    file_put_contents ('unencrypted.wav', openssl_decrypt ($inbuffer, $method, pack ("H*", "123456789abc1236789abc1236789abc"), true, pack("H*", "abcdef123defabcdef456defabcdef89")));