Search code examples
c#asp.netencryptionaesopayo

Encrypting Crypt field using asp.net webpages for SagePay Form Integration


I always get the an error: It is the Crypt field

 <form action="@SagePaySettings.FormPaymentUrl" method="POST" id="gopayment" name="gopayment">
        <input type="hidden" name="VPSProtocol" value="@SagePaySettings.ProtocolVersion.VersionString()">
        <input type="hidden" name="TxType" value="@SagePaySettings.DefaultTransactionType">
        <input type="hidden" name="Vendor" value="@SagePaySettings.VendorName">
        <input type="hidden" name="Crypt" value="@Crypt">

Could someone send encryption routine for asp.net Webpages in c#?

The sage pay team have been no help with this.

It Must be encrypted using AES(block size 128-bit) in CBC mode with PKCS#5 padding using the provided password as both the key and initialisation vector and encode the result in hex (making sure the letters are in upper case).


Solution

  • Hi After allot of searching i have manged this so wanted to show the answer just in case someone else needs this. I am in no doubt this could be done better as i am just a starting in asp and c#, But it works.

    using System;
    using System.Linq;
    using System.Security.Cryptography;
    using System.Text;
    using System.IO;
    
    public static class EncryptionHelper
    {
        private static byte[] keyAndIvBytes;
    
        static EncryptionHelper()
        {
            // You'll need a more secure way of storing this, I this isn't
            // a real key
            keyAndIvBytes = UTF8Encoding.UTF8.GetBytes("123123123123123b");
        }
    
        public static string ByteArrayToHexString(byte[] ba)
        {
            return BitConverter.ToString(ba).Replace("-", "");
        }
    
        public static byte[] StringToByteArray(string hex)
        {
            return Enumerable.Range(0, hex.Length)
                             .Where(x => x % 2 == 0)
                             .Select(x => Convert.ToByte(hex.Substring(x, 2), 16))
                             .ToArray();
        }
    
        public static string DecodeAndDecrypt(string cipherText)
        {
            string DecodeAndDecrypt = AesDecrypt(StringToByteArray(cipherText));
            return (DecodeAndDecrypt);
        }
    
        public static string EncryptAndEncode(string plaintext)
        {
            return ByteArrayToHexString(AesEncrypt(plaintext));
        }
    
        public static string AesDecrypt(Byte[] inputBytes)
        {
            Byte[] outputBytes = inputBytes;
    
            string plaintext = string.Empty;
    
            using (MemoryStream memoryStream = new MemoryStream(outputBytes))
            {
                using (CryptoStream cryptoStream = new CryptoStream(memoryStream, GetCryptoAlgorithm().CreateDecryptor(keyAndIvBytes, keyAndIvBytes), CryptoStreamMode.Read))
                {
                    using (StreamReader srDecrypt = new StreamReader(cryptoStream))
                    {
                        plaintext = srDecrypt.ReadToEnd();
                    }
                }
            }
    
            return plaintext;
        }
    
        public static byte[] AesEncrypt(string inputText)
        {
            byte[] inputBytes = UTF8Encoding.UTF8.GetBytes(inputText);//AbHLlc5uLone0D1q
    
            byte[] result = null;
            using (MemoryStream memoryStream = new MemoryStream())
            {
                using (CryptoStream cryptoStream = new CryptoStream(memoryStream, GetCryptoAlgorithm().CreateEncryptor(keyAndIvBytes, keyAndIvBytes), CryptoStreamMode.Write))
                {
                    cryptoStream.Write(inputBytes, 0, inputBytes.Length);
                    cryptoStream.FlushFinalBlock();
    
                    result = memoryStream.ToArray();
                }
            }
    
            return result;
        }
    
    
        private static RijndaelManaged GetCryptoAlgorithm()
        {
            RijndaelManaged algorithm = new RijndaelManaged();
            //set the mode, padding and block size
            algorithm.Padding = PaddingMode.PKCS7;
            algorithm.Mode = CipherMode.CBC;
            algorithm.KeySize = 128;
            algorithm.BlockSize = 128;
            return algorithm;
        }
    }
    

    I call the the class like so:-

    string crypt = "blahblahblah";
    string EncryptAndEncode = EncryptionHelper.EncryptAndEncode(crypt);
    string DecodeAndDecrypt = EncryptionHelper.DecodeAndDecrypt(EncryptAndEncode);