Client Management Systems API

Password Encryption Functionality


The password encryption functionality is based on the RSA public-key cryptosystem, and optionally an additional AES protocol Encryption layer.
The encrypted password may be presented to Saxo either by one of two manners:

  1. RSA Public Key Encryption Only

Using this method, the password presented (in base64) is encrypted using a public key. This public key will be generated by Saxo, and passed on to the WLC together with a KeySequence.

  1. RSA Public Key and AES Encryption

In this method, the password (in base64) is AES encrypted, using an encryption key. The encryption key (in base64) that the WLC uses to AES encrypt the password is also passed to Saxo, and is public-key encrypted.
Suggestion: The encryption key should be randomly generated on every password encryption.
Methods impacted by Password Encryption

  • ChangeUserPassword
  • CreateUser
  • UpdateUser
  • CreateCounterpart
  • ValidateUserPassword


All of the above methods will have the following new input items:

  • EncryptionInfo [Object]:
    • RSAKeySequenceNumber[Int]
    • AESKey[String]
  • PasswordIsEncrypted [Boolean]

How it works


RSA Public Key Generation:
Saxo Bank will generate a RSA public/private key pair. Saxo will keep the private key, and send the public key to the WLC, together with a RSAKeySequenceNumber (this id will be used by Saxo to identify the WLC setup within the Saxo system, it will be unique for the pair[WLC, PublicKey]).
Encrypting password:
When an encrypted password is going to be passed, via one of the methods above (a. or b.), the PasswordIsEncrypted field has to be set to "true" and the EncryptionInfo object needs to be filled in with the relevant encryption input (dependent on the methods of encryption chosen).
If you choose method a) RSA Public Key Encryption Only:

  • PasswordIsEncrypted = "true"
  • RSAKeySequenceNumber is always passed: this is the id that Saxo will pass to the WLC and that will identify the WLC's RSA config inside Saxo's systems.
  • Password is base64 RSA encrypted



If you choose method b) RSA Public Key and AES Encryption

  • PasswordIsEncrypted = "true"
  • RSAKeySequenceNumber is always passed: this is the id that Saxo will pass to the WLC and that will identify the WLC's RSA config inside Saxo's systems.
  • AESKey: this parameter has to be filled in with the RSA Encrypted value, of the base64 keyword, used to AES encrypt the password
  • Password is base64 AES encrypted

Code Samples


The below code is not prepared for live usage as is. The purpose of this code is to suggest and inspire implementations.

Sample code for AESkey generation

(AESKey has to be transformed into it a base64 format string before it is RSA encrypted and placed into the CMS request.)

          private void CreateAES256Key_Click(object sender, EventArgs e)
         {
             try
             {
                RijndaelManaged rjndl = new RijndaelManaged();
                 rjndl.KeySize = 256;
                 rjndl.BlockSize = 256;
                 rjndl.Mode = CipherMode.CBC;
                 rjndl.Padding = PaddingMode.PKCS7;
                 byte[] keyBytes = rjndl.Key;
                 string key = Convert.ToBase64String(keyBytes);
                 
                 AES256NewKeyTextBox.Text = key;
             }
             catch (Exception ex)
             {
                 MessageBox.Show(ex.Message);
             }
         }

Sample code for encrypting Password with AESkey.

        private void AES256EncryptButton_Click(object sender, EventArgs e)
         {
             try
             {
                 byte[] initializationVector = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
                 AesManaged encryptor = new AesManaged();
                 encryptor.Mode = CipherMode.CBC;
                 encryptor.Key = Convert.FromBase64String(AES256KeyTextBox.Text);
                 encryptor.IV = initializationVector;
                 encryptor.Padding = PaddingMode.PKCS7; 
                 using (MemoryStream cipherTextStream = new MemoryStream())
                 using (CryptoStream cryptoStream = new CryptoStream(cipherTextStream, encryptor.CreateEncryptor(), CryptoStreamMode.Write))
                 {
                     byte[] plainTextBytes = null;
                     if (AES256Base64CheckBox.Checked) plainTextBytes = Convert.FromBase64String(AES256InputTextBox.Text);
                     else plainTextBytes = (new UTF8Encoding(false)).GetBytes(AES256InputTextBox.Text);
                     cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
                     cryptoStream.FlushFinalBlock();
                     cryptoStream.Close();
                    AES256OutputTextBox.Text = Convert.ToBase64String(cipherTextStream.ToArray());
                     AESOutputUTF8TextBox.Text = String.Empty;
                 }
             }
             catch (Exception ex)
             {
                 MessageBox.Show(ex.Message);
             }
         }

Encrypting with RSA key

        private string RSAEncrypt(string rsaKeyXml, string inputStr, bool base64)
         {
             string outputBase64Str = null; 
             try
             {
                 RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
                 rsa.FromXmlString(rsaKeyXml);
                 byte[] inputBytes = null;
                 if (base64) inputBytes = Convert.FromBase64String(inputStr);
                 else inputBytes = (new UTF8Encoding(false)).GetBytes(inputStr);
                 byte[] outputBytes = rsa.Encrypt(inputBytes, false);
                 outputBase64Str = Convert.ToBase64String(outputBytes);
             }
             catch (Exception ex)
             {
                MessageBox.Show(ex.Message);
             }
             return outputBase64Str;
         }