Implementing Encryption and Decryption Functions via API in Business Central - CloudFronts

Implementing Encryption and Decryption Functions via API in Business Central

In Microsoft Dynamics 365 Business Central, securing sensitive data like passwords is crucial for protecting both businesses and customers. By the end of this post, you will understand how passwords are encrypted before being stored and decrypted only when necessary. This ensures that passwords remain secure, minimizing exposure and building trust.

1. Storing Encrypted Passwords

Passwords are encrypted before being stored in the database to ensure they are protected. This prevents anyone from accessing passwords in plain text, even if they gain unauthorized access to the database. Here’s an example of how a custom table, CFSCustomPage, stores encrypted passwords using the EncodePassword procedure.

In the above code, the password is encrypted before being stored in the database to ensure the data remains secure. The EncodePassword procedure is used for encrypting the password.

2. Decrypting Passwords When Needed

When passwords need to be retrieved, they are decrypted using the DecodePassword procedure. This ensures that passwords are only accessible when required, minimizing exposure. Here’s the decryption function:

In the above code, passwords are decrypted only when needed, allowing the system to securely handle sensitive data.

3. Returning Decrypted Passwords via API

For external systems or applications requiring access to customer data, Business Central ensures that passwords are only decrypted and transmitted securely via API. This way, customer information remains protected throughout the process. Here’s how the API Page CFSCustPageAPI handles this:

The API exposes the encrypted password and only decrypts it when accessed securely through the API.

4. Returning Decrypted Passwords in a List Page

Passwords can also be decrypted and displayed in a list page when necessary, ensuring they are only shown to authorized users. This is done using the DecodePassword function in the page CFSCustomPage, as shown below:

This page allows authorized users to view encrypted passwords, MD5, SHA1, SHA512, and AES encrypted passwords, and also decrypt them when necessary.

5. Best Practices for Password Security

  • Encrypt Passwords: Always encrypt passwords in the database to keep them secure.
  • Limit Decryption: Decrypt passwords only when necessary and restrict access to trusted users.
  • Secure Transmission: Use HTTPS to transmit decrypted passwords, ensuring they are protected during transmission.

6. Encryption Types Used in the System

Here are the different types of encryptions and hashing methods used in Business Central:

  1. MD5 Hashing:
    • MD5 (Message Digest Algorithm 5) produces a 128-bit hash and is commonly used for integrity checks. However, it is considered insecure for cryptographic purposes due to vulnerabilities.
  2. SHA-1 Hashing:
    • SHA-1 (Secure Hash Algorithm 1) produces a 160-bit hash. While it was widely used, it is now considered insecure because of vulnerabilities that allow collisions (two different inputs producing the same hash).
  3. SHA-512 Hashing:
    • SHA-512 is part of the SHA-2 family and produces a 512-bit hash. It is widely used for secure data integrity and is recommended for password hashing due to its strength.
  4. AES Encryption (Advanced Encryption Standard):
    • AES is a symmetric encryption algorithm used for securely encrypting sensitive data. It uses the same key for both encryption and decryption. AES supports multiple key sizes, including 128, 192, and 256 bits. It is widely considered secure and is commonly used for encrypting passwords.
  5. Base64 Encoding:
    • Base64 encoding is used to convert binary data (like encryption keys) into ASCII text, making it easier to transmit over text-based protocols like HTTP. It is often used to encode the encryption key and initialization vector (IV) in AES encryption.

Code:

table 71983576 CFSCustomPage

{

    Caption = ‘CustomPage’;

    DataClassification = ToBeClassified;

    fields

    {

        field(71983575; “No.”; Code[20])

        {

            Caption = ‘No.’;

            DataClassification = CustomerContent;

        }

        field(71983576; Name; Text[50])

        {

            Caption = ‘Name’;

            DataClassification = CustomerContent;

        }

        field(71983577; Password; Text[365])

        {

            Caption = ‘Password’;

            DataClassification = CustomerContent;

        }

    }

    keys

    {

        key(PK; “No.”)

        {

            Clustered = true;

        }

    }

    // Procedure to encode (encrypt) a password

    [ServiceEnabled]

    procedure EncodePassword(var Password: Text[365])

    var

        EncryptedPassword: Text[365];

    begin

        // Encrypt the password using the Encrypt function

        EncryptedPassword := Encrypt(Password);

        // Assign the encrypted password back to the Password field

        Password := EncryptedPassword;

    end;

    // Procedure to decode (decrypt) the password

    [ServiceEnabled]

    procedure DecodePassword(EncryptedPassword: Text[365]): Text

    var

        DecryptedPassword: Text;

    begin

        // Decrypt the password using the Decrypt function

        DecryptedPassword := Decrypt(EncryptedPassword);

        // Return the decrypted password

        exit(DecryptedPassword);

    end;

    // Procedure to generate MD5 hash of a password

    procedure MD5Hash(Pwd: Text): Text

    var

        CryptographyManagement: Codeunit “Cryptography Management”;

        HashAlgorithmType: Option MD5,SHA1,SHA256,SHA384,SHA512;

    begin

        // Generate and return the MD5 hash of the password

        exit(CryptographyManagement.GenerateHash(Pwd, HashAlgorithmType::MD5));

    end;

    // Procedure to generate SHA1 hash of a password

    procedure SHA1(Pwd: Text): Text

    var

        CryptographyManagement: Codeunit “Cryptography Management”;

        HashAlgorithmType: Option MD5,SHA1,SHA256,SHA384,SHA512;

    begin

        // Generate and return the SHA1 hash of the password

        exit(CryptographyManagement.GenerateHash(Pwd, HashAlgorithmType::SHA1));

    end;

    // Procedure to generate SHA512 hash of a password

    procedure SHA512(Pwd: Text): Text

    var

        CryptographyManagement: Codeunit “Cryptography Management”;

        HashAlgorithmType: Option MD5,SHA1,SHA256,SHA384,SHA512;

    begin

        // Generate and return the SHA512 hash of the password

        exit(CryptographyManagement.GenerateHash(Pwd, HashAlgorithmType::SHA512));

    end;

    // AES Encryption and Decryption example

    procedure AESEncryptionExample(Passowrd: Text): TEXT

    var

        RijndaelCryptography: Codeunit “Rijndael Cryptography”;

        Base64Convert: Codeunit “Base64 Convert”;

        EncryptedText: Text;

        DecryptedText: Text;

        SecretTexts: SecretText;

    begin

        // Convert the encryption key ‘1106198321061984’ to Base64 format and store it in SecretTexts

        SecretTexts := Base64Convert.ToBase64(‘1106198321061984’);

        // Set the encryption key and initialization vector (IV) using Base64-encoded values

        RijndaelCryptography.SetEncryptionData(SecretTexts, Base64Convert.ToBase64(‘ITGateWayXyZ1234’));

        // Set the AES block size to 128 bits (standard AES block size)

        RijndaelCryptography.SetBlockSize(128);

        // Set the cipher mode for AES to CBC (Cipher Block Chaining)

        RijndaelCryptography.SetCipherMode(‘CBC’);

        // Set the padding mode for AES encryption to PKCS7 (standard padding scheme for block ciphers)

        RijndaelCryptography.SetPaddingMode(‘PKCS7’);

        // Encrypt the password using AES encryption

        EncryptedText := RijndaelCryptography.Encrypt(Passowrd);

        // Decrypt the encrypted password using AES decryption

        DecryptedText := RijndaelCryptography.Decrypt(EncryptedText);

        // Return the encrypted password (only returning the encrypted text in this procedure)

        EXIT(EncryptedText);

    end;

    // Procedure to enable or check the encryption status

    procedure EnableEncryption()

    var

        DataEncryption: Codeunit 1266;

    begin

        // Check if encryption is enabled, then show a message

        if DataEncryption.IsEncryptionEnabled() then

            Message(‘Encryption is Enabled!’)

        else

            Message(‘Encryption is Disabled!’);

    end;

    // Trigger for inserting a new record: encrypt the password before storing it

    trigger OnInsert()

    begin

        // Encrypt the password before inserting the record

        EncodePassword(Rec.”Password”);

    end;

    // Trigger for modifying an existing record: re-encrypt the password if modified

    trigger OnModify()

    begin

        // Encrypt the password again before saving the changes

        EncodePassword(Rec.Password);

    end;

}

To conclude, by encrypting passwords and decrypting them only, when necessary, Business Central ensures that sensitive customer data is stored securely and handled responsibly. This approach not only helps businesses protect their users’ data but also builds trust by ensuring customers’ information is never exposed unnecessarily. By using various encryption and hashing methods such as MD5, SHA-1, SHA-512, and AES, you can choose the level of security required for your specific use case, ensuring robust data protection for all users.

This updated blog now incorporates the latest code changes, encryption methods, and security best practices, offering a more detailed explanation of how encryption is applied to password security in Business Central.

We hope you found this blog useful, and if you would like to discuss anything, you can reach out to us at transform@cloudfonts.com.


Share Story :

SEARCH BLOGS :

FOLLOW CLOUDFRONTS BLOG :


Secured By miniOrange