none
URGENT | ANYONE WHO KNOWS WHICH ENCRYPTION IS USED IN THIS CODE?

    Question

  • Right now, we are faced with a severe issue, our R&D guy do now much about JAVA, we have encrypt the data send to server, below is the code provided by our customer, but they have no idea either.

    Hope anyone who knows about it, would you please contact us?

    Your help is quite appreciated. Thanks in advance.

    static readonly string PasswordHash = "P@@Sw0rdkhallew";
            static readonly string SaltKey = "S@LT&KEYNEW";
            static readonly string VIKey = "@1B2c3D4e5F6g7H@12";

            public static string Encrypt(string plainText)
            {
                byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText);

                byte[] keyBytes = new Rfc2898DeriveBytes(PasswordHash, Encoding.ASCII.GetBytes(SaltKey)).GetBytes(256 / 8);
                var symmetricKey = new RijndaelManaged() { Mode = CipherMode.CBC, Padding = PaddingMode.Zeros };
                var encryptor = symmetricKey.CreateEncryptor(keyBytes, Encoding.ASCII.GetBytes(VIKey));

                byte[] cipherTextBytes;

                using (var memoryStream = new MemoryStream())
                {
                    using (var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
                    {
                        cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
                        cryptoStream.FlushFinalBlock();
                        cipherTextBytes = memoryStream.ToArray();
                        cryptoStream.Close();
                    }
                    memoryStream.Close();
                }
                return Convert.ToBase64String(cipherTextBytes);
            }
            public static string Decrypt(string encryptedText)
            {
                byte[] cipherTextBytes = Convert.FromBase64String(encryptedText);
     byte[] keyBytes = new Rfc2898DeriveBytes(PasswordHash, Encoding.ASCII.GetBytes(SaltKey)).GetBytes(256 / 8);
                var symmetricKey = new RijndaelManaged() { Mode = CipherMode.CBC, Padding = PaddingMode.None };

                var decryptor = symmetricKey.CreateDecryptor(keyBytes, Encoding.ASCII.GetBytes(VIKey));
                var memoryStream = new MemoryStream(cipherTextBytes);
                var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read);
                byte[] plainTextBytes = new byte[cipherTextBytes.Length];

                int decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length);
                memoryStream.Close();
                cryptoStream.Close();
                return Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount).TrimEnd("\0".ToCharArray());
            }

          
    Wednesday, March 29, 2017 2:47 AM

All replies

  • What you have there is AES.

    To be more precise, this is Rijndael which is the winner of the competition for selecting the AES algorithm (so basically it is AES with a little more freedom in selecting the key and block size). When you use it with the default constructor this is actually AES-256 (the most commonly used algorithm nowadays).

    Here is a link to the MSDN documentation: https://msdn.microsoft.com/en-us/library/system.security.cryptography.rijndaelmanaged(v=vs.110).aspx


    • Proposed as answer by bowman_d Saturday, April 1, 2017 10:22 AM
    Wednesday, March 29, 2017 5:52 AM
  • Thank you so much!

    We will run some more test.

    Do appreciate your help. 

    Wednesday, March 29, 2017 6:41 AM
  • Hi, sorry to bother again.

    can we use AES_cbc_encrypt in opensll?

    thank you.


    Wednesday, March 29, 2017 8:36 AM
  • You can use whatever implementation of AES you want. Nonetheless the code you provided uses some specific configurations:

    • key size: 256 bits
    • mode : CBC
    • padding: 0s
    • the key is generated from static information (PasswordHash, SaltKey) using Rfc2898
    • an Initialization vector is used

    So if you want to get exactly the same results as the provided code, you should use the same options. I have never used the openssl library, so I cannot be very helpful with the actual implementation.

    Wednesday, March 29, 2017 12:46 PM
  • hi, one more questions, thank you in advance:

    Can we use "PKCS5_PBKDF2_HMAC:

     PKCS5_PBKDF2_HMAC(password, strlen(password), salt, sizeof(salt), 1000, EVP_sha1(), 32, key)" in openssl

    to replace

    Rfc2898DeriveBytes?

    Robert

    Saturday, April 1, 2017 9:28 AM
  • Yes, this should work. I am not 100% sure that all arguments match the provided example, but at least at first glance they do.

    Good luck

    Monday, April 3, 2017 5:56 AM
  • Hi, best thanks to the ones who may help us with this.

    How to use C# to re-program the follow code(written in c/c++)?

      int ATransNetworkBS::encrypt(char *input_string, char *encrypt_string)
    {
    AES_KEY aes;
    char password[] = "P@@Sw0rdkhallew";  // AES_BLOCK_SIZE = 16
    unsigned char key[32];
    unsigned char salt[] = "S@LT&KEYNEW";
    //unsigned char salt[] = {0x53,0x40,0x4c,0x54,0x26,0x4b,0x45,0x59,0x4e,045,0x57};
    unsigned char iv[] = "@1B2c3D4e5F6g7H@12";   // init vector
    unsigned int len;  // encrypt length (in multiple of AES_BLOCK_SIZE)
    int nBei;
    EVP_MD *digest;

    printf("ATransNetworkBS::encrypt = %d %d\n", strlen(password), sizeof(salt));

    memset(key, 0, sizeof(key));
    printf("PKCS5_PBKDF2_HMAC_SHA1 =");
    if( PKCS5_PBKDF2_HMAC_SHA1(password, strlen(password), salt, sizeof(salt), 1000, 32, key) != 0 )
            {
                 for(int i=0;i<32;i++) { printf("%d ", key[i]); } printf("\n");
            }
            else
            {
                 printf("PKCS5_PBKDF2_HMAC_SHA1 failed .5\n");
            }  


    // set the encryption length
    len = 0;
    if ((strlen(input_string) + 1) % 16 == 0) 
    {
    len = strlen(input_string) + 1;

    else 
    {
    len = ((strlen(input_string) + 1) / 16 + 1) * 16;
    }

    printf("ATransNetworkBS::encrypt.0 = %d %d\n", len, strlen(input_string));
    for(int i=0; i<len; i++)
    {
    printf("%c",input_string[i]);
    }
    printf("\r\n");
       
    if (AES_set_encrypt_key(key, 256, &aes) < 0) {  
     printf("Unable to set encryption key in AES\n");
    return 0;
    }  

    // encrypt (iv will change)
    AES_cbc_encrypt((unsigned char*)input_string, (unsigned char*)encrypt_string, len, &aes, iv, AES_ENCRYPT);

    printf("ATransNetworkBS::encrypt.0 = %d\n", len);
    for(int i=0; i<len; i++)
    {
    printf("%c",encrypt_string[i]);
    }
    printf("\r\n");

    return len;      
    }

    Thank you in advance.


    Robert Jiang

    Monday, April 10, 2017 7:18 AM
  • Hi, can you help us with this?

    how to use C# to re-program the follow code(written in c/c++)?

      int ATransNetworkBS::encrypt(char *input_string, char *encrypt_string)
    {
    AES_KEY aes;
    char password[] = "P@@Sw0rdkhallew";  // AES_BLOCK_SIZE = 16
    unsigned char key[32];
    unsigned char salt[] = "S@LT&KEYNEW";
    //unsigned char salt[] = {0x53,0x40,0x4c,0x54,0x26,0x4b,0x45,0x59,0x4e,045,0x57};
    unsigned char iv[] = "@1B2c3D4e5F6g7H@12";   // init vector
    unsigned int len;  // encrypt length (in multiple of AES_BLOCK_SIZE)
    int nBei;
    EVP_MD *digest;

    printf("ATransNetworkBS::encrypt = %d %d\n", strlen(password), sizeof(salt));

    memset(key, 0, sizeof(key));
    printf("PKCS5_PBKDF2_HMAC_SHA1 =");
    if( PKCS5_PBKDF2_HMAC_SHA1(password, strlen(password), salt, sizeof(salt), 1000, 32, key) != 0 )
            {
                 for(int i=0;i<32;i++) { printf("%d ", key[i]); } printf("\n");
            }
            else
            {
                 printf("PKCS5_PBKDF2_HMAC_SHA1 failed .5\n");
            }  


    // set the encryption length
    len = 0;
    if ((strlen(input_string) + 1) % 16 == 0) 
    {
    len = strlen(input_string) + 1;

    else 
    {
    len = ((strlen(input_string) + 1) / 16 + 1) * 16;
    }

    printf("ATransNetworkBS::encrypt.0 = %d %d\n", len, strlen(input_string));
    for(int i=0; i<len; i++)
    {
    printf("%c",input_string[i]);
    }
    printf("\r\n");
       
    if (AES_set_encrypt_key(key, 256, &aes) < 0) {  
     printf("Unable to set encryption key in AES\n");
    return 0;
    }  

    // encrypt (iv will change)
    AES_cbc_encrypt((unsigned char*)input_string, (unsigned char*)encrypt_string, len, &aes, iv, AES_ENCRYPT);

    printf("ATransNetworkBS::encrypt.0 = %d\n", len);
    for(int i=0; i<len; i++)
    {
    printf("%c",encrypt_string[i]);
    }
    printf("\r\n");

    return len;      
    }

    Thank you in advance.


    Robert Jiang

    Monday, April 10, 2017 7:18 AM
  • Well, the original question code has almost identical function written in plain C#

    Do you have any specific issues with translating the code?

    Monday, April 10, 2017 2:16 PM