Skip to content

C implementation of Rob Napier's RNCryptor data format specification

License

Notifications You must be signed in to change notification settings

RNCryptor/RNCryptor-C

Repository files navigation

RNCryptor-C

A C implementation of Rob Napier’s Objective-C library RNCryptor's data format specification. This implementation supports Data Format Specification v3. Please note, this is not a port of RNCryptor, rather an implementation of the RNCryptor’s Data Format Specification v3 in C. I wrote this because I like RNCryptor and I use it in iOS. I wanted to decrypt RNCryptor’s encrypted files in other platforms but I found the most implementations of RNCryptor’s specification are incomplete, buggy and shear lack of documentation. I’m releasing it with the hope that you’ll find it useful. Suggestions, bug reports are always welcome. If you have any question, request or suggestion, please enter it in the Issues with appropriate label.

Requirements

  • OpenSSL header files and libraries

Features

  • Supports RNCryptor’s password and key based encryption/decryption.

  • Auto generated or caller generated Encryption salt, HMAC salt and IV

  • Custom KDF iteration number. Currently must use RNCryptor’s default 10,000 (use the define RNCRYPTOR3_KDF_ITER) if interoperability with RNCryptor’s encrypted files is required.

  • Passes RNCryptor’s Test Vectors. Look at Testing section.

Please look at the APIs section for details.

Supported Platforms

  • Linux/Unix

  • MacOS X

  • Microsoft Windows

It should compile on any POSIX compliant system. Works on 64 bit systems.

Versions

Latest stable version is 1.06. Please look at the ChangeLog for details on changes.

Downloads

Please download the latest stable source from releases page.

Bug fixes and stable features are merged from dev branch to master branch every now and then. Clone the repo if you want the latest code.

How to compile/install

Linux/Unix/MacOS X

Specify the path of OpenSSL with configure to generate the Makefile

$ ./configure --with-openssl=/usr
$ ./configure --with-openssl=/usr/local/ssl
$ make clean
$ make
$ make examples
$ sudo make install

The header file rncryptor_c.h will be installed in /usr/local/include, the library librncryptorc.a will be installed in /usr/local/lib, the example programs will be installed in /usr/local/bin

Note
If you use the library in your code, you must link with openssl libraries. For testing the code, plese look at the Testing section

The example programs are:

  • rn_encrypt - Encrypts a file with a password

  • rn_encrypt_with_key - Encrypts a file with an encryption key. Also requires a HMAC key for creating HMAC-SHa256 digest

  • run_decrypt - Decypts a file with a password

  • rn_decrypt_with_key - Decrypts a file with an encryption key. Also requires a HMAC key for verifying HMAC-SHA256 digest.

Please look at the example programs' source to see how the APIs are used. Look at Example Programs sections for usage.

Microsoft Windows

Requirements

  • Microsoft Visual Studio 2010 and 2013 (can be downloaded from microsoft). Make sure to run the appropriate batch file before starting compiling. For example run vsvars32.bat for VS 2010.

  • OpenSSL libraries and header files. Look at INSTALL.32 that comes with OpenSSL on how to compile and install OpenSSL. Makefile.nmake expects it to be installed at c:\openssl

Open a command shell and type:

c:\> nmake -f Makefile.nmake
c:\> name -f Makefile.nmake examples

The static library rncryptorc.lib and example programs will be created.

Note
If you use the library in your code, you must link with openssl libraries.

The example programs are:

  • run_encrypt.exe

  • rn_encrypt_with_key.exe

  • rn_decrypt.exe

  • rn_decrypt_with_key.exe

Please look at the example programs' source to see how the APIs are used. Look at Example Programs sections for usage.

Testing

  • Simple sanity test (requires ruby 2), run in unix:

$ make test_simple
ruby tests/test.rb
MiniTest::Unit::TestCase is now Minitest::Test. From tests/test.rb:10:in `<main>'
Run options: --seed 2146

# Running:

.DECRYPT WITH PASSWORD: PASSED
.ENCRYPT WITH KEY: PASSED
.DECRYPT WITH KEY: PASSED
.ENCRYPT WITH PASSWORD: PASSED
.DECRYPT WITH PASSWORD: PASSED
.DECRYPT TEXTFILE WITH PASSWORD: PASSED
..

Finished in 0.235094s, 29.7753 runs/s, 38.2826 assertions/s.

7 runs, 9 assertions, 0 failures, 0 errors, 0 skips

In Linux/Unix/MacOS X, to generate test code, compile and run, type:

$ make test

In Windows, to compile the test code and run, type:

c:\> nmake -f Makefile.nmake test
Microsoft (R) Program Maintenance Utility Version 10.00.30319.01
Copyright (C) Microsoft Corporation.  All rights reserved.

        cl /DWINNT /DWIN32 /DHAVE_MALLOC_H /DHAVE_STRING_H /DHAVE_FCNTL_H /DHAVE_CTYPE_H /DHAVE_STDLIB_H /DHAVE_OPENSSL /I. /Ic:/openssl/include /Ox /W3 /wd4996 /nologo tests/test_with_test_vectors.c rncryptorc.lib c:/openssl/lib/libeay32.lib c:/openssl/lib/ssleay32.lib ws2_32.lib shell32.lib advapi32.lib user32.lib gdi32.lib winmm.lib comdlg32.lib comctl32.lib /Fetests/test_with_test_vectors.exe test_with_test_vectors.c
        tests\test_with_test_vectors.exe

Verify v3_kdf
 One byte: PASSED
 Short password: PASSED
 Passphrase: PASSED
 Long passphrase: PASSED
 Multibyte: PASSED
 Mixed language: PASSED
Verify v3_password
 All fields empty or zero (with one-byte password): PASSED
 One byte: PASSED
 Exactly one block: PASSED
 More than one block: PASSED
 Multibyte password: PASSED
 Longer text and password: PASSED
Verify v3_key
 All fields empty or zero: PASSED
 One byte: PASSED
 Exactly one block: PASSED
 More than one block: PASSED

RNCryptor Data Formats

I am depicting RNCryptor’s data format v3 here little more clearly for myself.

Note
These are only for me, please look the RNCryptor’s Official Data Format Specification if you need to implement it in some other language.

Data format for Password based encryption

                                          1   1   1   1   1   1
  0   1   2   3   4   5   6   7   8   9   0   1   2   3   4   5
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| v | o |       Encryption Salt         |      HMAC Salt        /
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
/       |                       IV                              /
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
/       |          Ciphter Text. variable length                /
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|                               HMAC-SHA256                     |
|                                                               |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+

   v = version : 1 Byte (0x03)
   o = options : 1 Byte (0x01)
encryption salt: 8 Bytes
      HMAC Salt: 8 Bytes
             IV: 16 Bytes
    Cipher Text: Variable Length
    HMAC-SHA256: 32 Bytes

Data format for Key based encryption

                                          1   1   1   1   1   1
  0   1   2   3   4   5   6   7   8   9   0   1   2   3   4   5
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| v | o |                       IV                              /
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
/       |        cipher text. variable length                   /
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|                           HMAC-SHA256                         |
|                                                               |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+

   v = version : 1 Byte (0x03)
   o = options : 1 Byte (0x00)
             IV: 16 Bytes
    Cipher Text: Variable Length
    HMAC-SHA256: 32 Bytes

APIs

Note
The header file rncryptor_c.h has all the APIs fully documented.
Table 1. RNCryptor-C APIs
Function Name Description

rncryptorc_encrypt_file_with_password()

Encrypt a file with a password. Encryption salt, HMAC salt and IV are auto generated.

rncryptorc_encrypt_file_with_key()

Encrypt a file with a key. Caller will pass Encryption key and HMAC key. IV is auto generated

rncryptorc_decrypt_file_with_password()

Decrypt a file with a password

rncryptorc_decrypt_file_with_key()

Decrypt a file with a key. Caller will pass Encryption key and HMAC key

rncryptorc_encrypt_data_with_password()

Encrypt data with a password. Encryption salt, HMAC salt and IV are auto generated

rncryptorc_encrypt_data_with_password_with_salts_and_iv

Encrypt data with a password. Caller Will pass Encryption salt, HMAC salt and IV

rncryptorc_encrypt_data_with_key()

Encrypt data with a key. Caller will pass Encryption key and HMAC key. IV is auto generated

rncryptorc_encrypt_data_with_key_iv()

Encrypt data with a key. Caller will pass Encryption key, HMAC key and IV

rncryptorc_decrypt_data_with_password()

Decrypt data with a password

rncryptorc_decrypt_data_with_key()

Decrypt data with a key. Caller will pass Encryption key and HMAC key

rncryptorc_read_file()

Read and return the content of a file

rncryptorc_write_file()

Write data to a file

rncryptorc_set_debug()

Turn debug messages on or off

#include "rncryptor_c.h"
/*
**  Encrypt a file with a password. Encryption salt, HMAC salt and IV are auto generaed
**
**  Parameters:
**     infile_path    Path of the input file, can not be empty
**     kdf_iter       PBKDF2 iterations. Must Pass RNCRYPTOR3_KDF_ITER for RNCryptor
**                    data format sepc v3
**     password       Password for encryption, can not be empty
**     password_len   Length of the password
**     outdata_len    Returns. Length of the returned encryped data
**     errbuf         Buffer to write error to
**     errbuf_len     Length of errbuf
**
**  Return Values:
**     Pointer to encyrped data on success, NULL on failure
**     In case of failure errbuf will have the error message
**
**  Side Effects:
**     Memory is allocated for returned data. It is caller's responsibility to free it.
**
**  Comments:
**     The encryption is done as per RNCryptor data format specification v3.
**
**  Development History:
**   [email protected] May-20-2015 - first cut
*/
unsigned char *rncryptorc_encrypt_file_with_password(const char *infile_path,
        int kdf_iter,
        const char *password,
        int password_length,
        int *outdata_len,
        char *errbuf,
        int errbuf_len);
/*
**  Encrypt a file with a encryption key. HMAC key is also requried for
**  creating the HMAC-SHA256 digest. IV is auto generated.
**
**  Parameters:
**     infile_path    Path of the input file. Required.
**     kdf_iter       PBKDF2 iterations. Must Pass RNCRYPTOR3_KDF_ITER for RNCryptor
**                    data format sepc v3
**     encryption_key 32 byte long encryption key. Required.
**     hmac_key       32 byte long HMAC key. Required.
**     outdata_len    Returns. Length of the returned encryped data
**     errbuf         Buffer to write error to
**     errbuf_len     Length of errbuf
**
**  Return Values:
**     Pointer to encyrped data on success, NULL on failure
**     In case of failure errbuf will have the error message
**
**  Side Effects:
**     Memory is allocated for returned data. It is caller's responsibility to free it.
**
**  Comments:
**     The encryption is done as per RNCryptor data format specification v3.
**
**  Development History:
**   [email protected] May-20-2015 - first cut
*/
unsigned char *rncryptorc_encrypt_file_with_key(const char *infile_path,
        int kdf_iter,
        const unsigned char *encr_key,
        const unsigned char *hmac_key,
        int *outdata_len,
        char *errbuf,
        int errbuf_len);
/*
**  Decrypt a file with a password
**
**  Parameters:
**     infile_path    Path of the file to decrypt. Required
**     kdf_iter       PBKDF2 iterations. Must Pass RNCRYPTOR3_KDF_ITER for RNCryptor
**                    data format sepc v3
**     password       Password for decryption. Requied
**     password_len   Length of the password
**     outdata_len    Returns. Length of the returned decrypted data
**     errbuf         Buffer to write error to
**     errbuf_len     Length of errbuf
**
**  Return Values:
**     Pointer to decrypted data on success, NULL on failure.
**     In case of failure, errbuf will have the error message
**
**  Side Effects:
**     Memory is allocated for returned data. It is caller's responsibility to free it.
**
**  Comments:
**    The encryption is done as per RNCryptor data format specification v3.
**
**  Development History:
**   [email protected] May-20-2015 - first cut
*/
unsigned char *rncryptorc_decrypt_file_with_password(const char *infile_path,
        int kdf_iter,
        const char *password,
        int password_length,
        int *outdata_len,
        char *errbuf,
        int errbuf_len)
/*
**  Decrypt a file with a encryption key. HMAC key is also requried for
**  verifying the HMAC-SHA256 digest
**
**  Parameters:
**     infile_path    Path of the input file. Required.
**     kdf_iter       PBKDF2 iterations. Must Pass RNCRYPTOR3_KDF_ITER for RNCryptor
**                    data format sepc v3
**     encryption_key 32 byte long encryption key. Required.
**     hmac_key       32 byte long HMAC key. Required.
**     outdata_len    Returns. Length of the returned encryped data
**     errbuf         Buffer to write error to
**     errbuf_len     Length of errbuf
**
**  Return Values:
**     Pointer to deccyrped data on success, NULL on failure.
**     In case of failure, errbuf will have the error message
**
**  Side Effects:
**     Memory is allocated for returned data. It is caller's responsibility to free it.
**
**  Comments:
**    The encryption is done as per RNCryptor data format specification v3.
**
**  Development History:
**   [email protected] May-20-2015 - first cut
*/
unsigned char *rncryptorc_decrypt_file_with_key(const char *infile_path,
        int kdf_iter,
        const unsigned char *encr_key,
        const unsigned char *hmac_key,
        int *outdata_len,
        char *errbuf,
        int errbuf_len)
/*
**  Encrypt data with a password. Encryption salt, HMAC salt and IV are auto generated.
**
**  Parameters:
**     indata         Pointer to data to encrypt. Required
**     indata_len     Length of the data in bytes
**     kdf_iter       PBKDF2 iterations. Must Pass RNCRYPTOR3_KDF_ITER for RNCryptor
**                    data format sepc v3
**     password       Password for encryption, can not be empty
**     password_len   Length of the password
**     outdata_len    Returns. Length of the returned encryped data
**     errbuf         Buffer to write error to
**     errbuf_len     Length of errbuf
**
**  Return Values:
**     Pointer to encyrped data on success, NULL on failure.
**     In case of failure errbuf will have the error message
**
**  Side Effects:
**     Memory is allocated for returned data. It is caller's responsibility to free it.
**
**  Comments:
**     The encryption is done as per RNCryptor data format specification v3.
**
**  Development History:
**   [email protected] May-20-2015 - first cut
*/
unsigned char *rncryptorc_encrypt_data_with_password(const unsigned char *indata,
        int indata_len,
        int kdf_iter,
        const char *password,
        int password_length,
        int *out_data_len,
        char *errbuf,
        int errbuf_len)
/*
**  Encrypt data with a password. Caller will pass encryption salt, hmac salt and iv
**
**  Parameters:
**     indata         Pointer to data to encrypt. Required
**     indata_len     Length of the data in bytes
**     kdf_iter       PBKDF2 iterations. Must Pass RNCRYPTOR3_KDF_ITER for RNCryptor
**                    data format sepc v3
**     password       Password for encryption, can not be empty
**     password_len   Length of the password
**     encr_salt_8    8 byte long encryption salt. Required.
**     hmac_salt_8    8 byte long hmac salt. Required.
**     iv_16          16 byte long iv. Required.
**     outdata_len    Returns. Length of the returned encryped data
**     errbuf         Buffer to write error to
**     errbuf_len     Length of errbuf
**
**  Return Values:
**     Pointer to encyrped data on success, NULL on failure.
**     In case of failure errbuf will have the error message
**
**  Side Effects:
**     Memory is allocated for returned data. It is caller's responsibility to free it.
**
**  Comments:
**     The encryption is done as per RNCryptor data format specification v3.
**
**  Development History:
**   [email protected] May-30-2015 - first cut
*/
unsigned char *rncryptorc_encrypt_data_with_password_with_salts_and_iv(const unsigned char *indata,
        int indata_len,
        int kdf_iter,
        const char *password,
        int password_length,
        unsigned char *encr_salt_8,
        unsigned char *hmac_salt_8,
        unsigned char *iv_16,
        int *outdata_len,
        char *errbuf,
        int errbuf_len)
/*
**  Encrypt data with a encryption key. HMAC key is also requried for
**  creating the HMAC-SHA256 digest. IV is auto generated.
**
**  Parameters:
**     indata         Pointer to input data to encrypt. Required.
**     indata_len     Length of the input data in bytes
**     kdf_iter       PBKDF2 iterations. Must Pass RNCRYPTOR3_KDF_ITER for RNCryptor
**                    data format sepc v3
**     encryption_key 32 byte long encryption key. Required.
**     hmac_key       32 byte long HMAC key. Required.
**     outdata_len    Returns. Length of the returned encryped data
**     errbuf         Buffer to write error to
**     errbuf_len     Length of errbuf
**
**  Return Values:
**     Pointer to encyrped data on success, NULL on failure
**     In case of failure errbuf will have the error message
**
**  Side Effects:
**     Memory is allocated for returned data. It is caller's responsibility to free it.
**
**  Comments:
**     The encryption is done as per RNCryptor data format specification v3.
**     It is caller's responsibility to pass valid arguments.
**
**  Development History:
**   [email protected] May-20-2015 - first cut
*/
unsigned char *rncryptorc_encrypt_data_with_key(const unsigned char *indata,
        int indata_len,
        int kdf_iter,
        const unsigned char *encryption_key,
        const unsigned char *hmac_key,
        int *out_data_len,
        char *errbuf,
        int errbuf_len)
/*
**  Encrypt data with a encryption key. Caller will pass encryption key, hmac key and iv
**
**  Parameters:
**     indata         Pointer to input data to encrypt. Required.
**     indata_len     Length of the input data in bytes
**     kdf_iter       PBKDF2 iterations. Must Pass RNCRYPTOR3_KDF_ITER for RNCryptor
**                    data format sepc v3
**     encr_key_32    32 byte long encryption key. Required.
**     hmac_key_32    32 byte long HMAC key. Required.
**     iv_16          16 byte long IV. Requied.
**     outdata_len    Returns. Length of the returned encryped data
**     errbuf         Buffer to write error to
**     errbuf_len     Length of errbuf
**
**  Return Values:
**     Pointer to encyrped data on success, NULL on failure
**     In case of failure errbuf will have the error message
**
**  Side Effects:
**     Memory is allocated for returned data. It is caller's responsibility to free it.
**
**  Comments:
**     The encryption is done as per RNCryptor data format specification v3.
**     It is caller's responsibility to pass valid arguments.
**
**  Development History:
**   [email protected] May-30-2015 - first cut
*/
unsigned char *rncryptorc_encrypt_data_with_key_iv(const unsigned char *indata,
        int indata_len,
        int kdf_iter,
        const unsigned char *encr_key_32,
        const unsigned char *hmac_key_32,
        const unsigned char *iv_16,
        int *outdata_len,
        char *errbuf,
        int errbuf_len)
/*
**  Decrypt data with a password
**
**  Parameters:
**     indata         Pointer to input data to encrypt. Required.
**  indata_len        Length of the input data in bytes
**     kdf_iter       PBKDF2 iterations. Must Pass RNCRYPTOR3_KDF_ITER for RNCryptor
**                    data format sepc v3
**     password       Password for decryption. Requied
**     password_len   Length of the password
**     outdata_len    Returns. Length of the returned decrypted data
**     errbuf         Buffer to write error to
**     errbuf_len     Length of errbuf
**
**  Return Values:
**     pointer to decrypted data on success, NULL on failure
**     In case of failure, errbuf will have the error message
**
**  Side Effects:
**     Memory is allocated for returned data. It is caller's responsibility to free it.
**
**  Comments:
**    The encryption is done as per RNCryptor data format specification v3.
**
**  Development History:
**   [email protected] May-20-2015 - first cut
*/
unsigned char *rncryptorc_decrypt_data_with_password(const unsigned char *indata,
        int indata_len,
        int kdf_iter,
        const char *password,
        int password_length,
        int *out_data_len,
        char *errbuf,
        int errbuf_len)
/*
**  Decrypt a file with a encryption key. HMAC key is also requried for
**  verifying the HMAC-SHA256 digest
**
**  Parameters:
**     indata         Pointer to input data to encrypt. Required.
**  indata_len        Length of the input data in bytes
**     kdf_iter       PBKDF2 iterations. Must Pass RNCRYPTOR3_KDF_ITER for RNCryptor
**                    data format sepc v3
**     encryption_key 32 byte long encryption key. Required.
**     hmac_key       32 byte long HMAC key. Required.
**     outdata_len    Returns. Length of the returned encryped data
**     errbuf         Buffer to write error to
**     errbuf_len     Length of errbuf
**
**  Return Values:
**     Pointer to deccyrped data on success, NULL on failure.
**     In case of failure, errbuf will have the error message.
**
**  Side Effects:
**     Memory is allocated for returned data. It is caller's responsibility to free it.
**
**  Comments:
**    The encryption is done as per RNCryptor data format specification v3.
**
**  Development History:
**   [email protected] May-20-2015 - first cut
*/
unsigned char *rncryptorc_decrypt_data_with_key(const unsigned char *indata,
        int indata_len,
        int kdf_iter,
        const unsigned char *encr_key,
        const unsigned char *hmac_key,
        int *outdata_len,
        char *errbuf,
        int errbuf_len)
/*
**  Read and return the content of a file
**
**  Parameters:
**      path   Path of the file to read
**      length Length of the data. returns.
**
**  Return Values:
**      pointer to content of file on success, NULL on failure
**
**  Side Effects:
**      Memory is allocated for the returned data, the caller is responsible
**      to free it
**
**  Comments:
**      Just a Helper function
**
**  Development History:
**   [email protected] May-20-2015 - first cut
*/
unsigned char *rncryptorc_read_file(const char *path,int *length);
/*
**  Write data to a file
**
**  Parameters:
**      outfile_path   Path of the output file
**      data           Pointer to data
**      data_len       Length of data
**
**  Return Values:
**      SUCCESS or FAILURE
**
**  Side Effects:
**      none
**
**  Comments:
**      Just a Helper function
**
**  Development History:
**   [email protected] May-20-2015 - first cut
*/
int rncryptorc_write_file(const char *outfile_path,const unsigned char *data,int data_len)
/*
**  Turn on/off debug messages. Default is off
**
**  Parameters:
**      d      Debug value. 1 or 0. To print the debug messages to stdout,
**             call the function with 1 before calling any API
**
**  Return Values:
**      None
**
**  Side Effects:
**      none
**
**  Comments:
**      Just a Helper function
**
**  Development History:
**   [email protected] May-20-2015 - first cut
*/
void rncryptorc_set_debug(int d)

Example Programs

If output file is specified as -, the data will be written to stdout.

  • rn_encrypt - Encrypt a file with a password

$ rn_encrypt
RNCryptor-C v1.03

An example program of RNCryptor-C. RNCryptor-C is a C implementation
of RNCryptor's data format spec v3

  RNCryptor:https://github.com/RNCryptor/RNCryptor
RNCryptor-C:https://github.com/RNCryptor/RNCryptor-C

Usage: rn_encrypt <file.plain> <file.enc>

Set the password with env variable RNCPASS
Exmaple:
In Linux/Unix:
  RNCPASS="secret";export RNCPASS
In Windows:
  SET RNCPASS=secret
  • rn_encrypt_with_key - Encrypt a file with a, encryption key. HMAC key also has to be specified for creating HMAC-SHA256 digest. The keys must be 32 bytes long.

$ rn_encrypt_with_key
RNCryptor-C v1.03

An example program of RNCryptor-C. RNCryptor-C is a C implementation
of RNCryptor's data format spec v3

  RNCryptor:https://github.com/RNCryptor/RNCryptor
RNCryptor-C:https://github.com/RNCryptor/RNCryptor-C

Usage: rn_encrypt_with_key <encrkeyfile.bin> \
  <hmackeyfile.bin> <file.plain> <file.enc>

Note: keys must be 32 bytes long
  • rn_decrypt - Decrypt a file with a password

$ rn_decrypt
RNCryptor-C v1.03

An example program of RNCryptor-C. RNCryptor-C is a C implementation
of RNCryptor's data format spec v3

  RNCryptor:https://github.com/RNCryptor/RNCryptor
RNCryptor-C:https://github.com/RNCryptor/RNCryptor-C

Usage: rn_decrypt <file.enc> <file.plain>

Set the password with env variable RNCPASS
Exmaple:
In Linux/Unix:
  RNCPASS="secret";export RNCPASS
In Windows:
  SET RNCPASS=secret
  • rn_decrypt_with_key - Decrypt a file win encryption key. HMAC key also has to be specified for verifying the HMAC-SHA256 digest. The keys must be 32 bytes long.

Example:

The file test/image.enc is a JPEG image encrypted on iOS with passsword test. To decrypt the file, set the password with environment variable RNCPASS

$ RNCPASS="test"; export RNCPASS
$ ./rn_decrypt test/imge.inc image.jpg
libcryptorc: rncryptor_c.c:143 - input data size 617650 bytes
libcryptorc: rncryptor_c.c:908 - Decoding ..
libcryptorc: rncryptor_c.c:339 - Cipher text length 617584
libcryptorc: rncryptor_c.c:925 - Decoded version 0x03 options 0x01
libcryptorc: rncryptor_c.c:929 - Verifying HMAC-SHA256 digest
libcryptorc: rncryptor_c.c:935 - HMAC verified
libcryptorc: rncryptor_c.c:939 - Deriving Cipher key with salt, iteration 10000
libcryptorc: rncryptor_c.c:952 - Encryption key derived
libcryptorc: rncryptor_c.c:958 - Decrypting..
libcryptorc: rncryptor_c.c:966 - Done decrypting, output length 617568 bytes
rn_decrypt.c:57 - Decrypted to image.jpg
Note
In Windows, when setting the password from command line, do not use any quotes around it. Type SET RNCPASS=secret and NOT SET RNCPASS="secret"

Write the output to stdout:

  • On MacOS X, write the image to stdout and display using preview

$ ./rn_decrypt test/image.inc - | open -a preview -f
  • On Linux, write the image to stdout and display using ImageMagick's display program

$ ./rn_decrypt test/image.inc - | display -
libcryptorc: rncryptor_c.c:143 - input data size 617650 bytes
libcryptorc: rncryptor_c.c:908 - Decoding ..
libcryptorc: rncryptor_c.c:339 - Cipher text length 617584
libcryptorc: rncryptor_c.c:925 - Decoded version 0x03 options 0x01
libcryptorc: rncryptor_c.c:929 - Verifying HMAC-SHA256 digest
libcryptorc: rncryptor_c.c:935 - HMAC verified
libcryptorc: rncryptor_c.c:939 - Deriving Cipher key with salt, iteration 10000
libcryptorc: rncryptor_c.c:952 - Encryption key derived
libcryptorc: rncryptor_c.c:958 - Decrypting..
libcryptorc: rncryptor_c.c:966 - Done decrypting, output length 617568 bytes
  • rn_decrypt_with_key - Dncrypt a file with a encryption key. HMAC key also has to be specified for verifying the HMAC-SHA256 digest. The keys must be 32 bytes long

$ rn_decrypt_with_key
RNCryptor-C v1.01

An example program of RNCryptor-C. RNCryptor-C is a C implementation
of RNCryptor's data format spec v3

  RNCryptor:https://github.com/RNCryptor/RNCryptor
RNCryptor-C:https://github.com/muquit/RNCryptor-C

Usage: rn_decrypt_with_key <encrkeyfile.bin> \
  <hmackeyfile.bin> <file.enc> <file.plain>

Note: keys must be 32 bytes long

Example:

$./rn_decrypt_with_key tests/encrkey.bin tests/hmackey.bin \
  tests/test_withkey.enc - 2>/dev/null
this is a test
Note
The encryption and hmac keys are generated with openssl:
$ openssl rand 32 -out tests/encrkeyfile.bin
$ openssl rand 32 -out tests/hmackey.bin

FAQ

  1. How big are the encrypted output size than the plain text?

RNCryptor’s data format v3 uses cipher type AES-256-CBC (AES encryption with 256 bytes long key in CBC mode). In CBC mode, input must have a lenght multiple of block size, therefore input will be padded if necessary.

The encrypted output length can be determined by the following formula:

  • For password based encryption

output_size = header_size + ciphertext_size + hamc_size
  header_size = 34
   block_size = 16
ciphertext_size = plaintext_size + block_size - (plaintext_size % block_size)

If a plaintext size is say 12 bytes:

ciphertext_size = 12 + 16 - (12 % 16)
                = 12 + 16 - 12
                = 16

Note the padding of 4 bytes

output_size = 34 + 16 + 32
            = 82 bytes

License

The MIT License (MIT)

Copyright (c) 2015-2020 Muhammad Muquit (https://www.muquit.com/)

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

This document is created with AsciidocFX