using System; using System.Web; using System.Web.UI; using System.Web.Security; using System.Text; using System.IO; using System.Security.Cryptography; using System.Configuration; using System.Linq; namespace EnVisage.Code.UserVoice { public class UserVoiceGenerator { public static string create(string userDetails) { // If you're acme.uservoice.com then this value would be 'acme' string uservoiceSubdomain = "planitppm"; // Get this from your UserVoice General Settings page string ssoKey = "036ccf37723654d432855e17635cbc08"; string initVector = "OpenSSL for Ruby"; // DO NOT CHANGE byte[] initVectorBytes = Encoding.UTF8.GetBytes(initVector); byte[] keyBytesLong; //---- this needs a TODO: refactor to either system preference or ClientControl - swappable ticket systems/URLs string uservoiceConfigSubDomain = string.Empty; bool activateUserVoice = true; if (ConfigurationManager.AppSettings.AllKeys.Contains("ActivateUserVoice")) activateUserVoice = Convert.ToBoolean(ConfigurationManager.AppSettings["ActivateUserVoice"]); //---- If UserVoice is not active, do an empty string return. if (activateUserVoice == false) return string.Empty; if (ConfigurationManager.AppSettings.AllKeys.Contains("UserVoiceSubDomain")) uservoiceConfigSubDomain = ConfigurationManager.AppSettings["UserVoiceSubDomain"]; if (uservoiceConfigSubDomain.Length > 0) uservoiceSubdomain = uservoiceConfigSubDomain; //---- //---- using ( SHA1CryptoServiceProvider sha = new SHA1CryptoServiceProvider() ) { keyBytesLong = sha.ComputeHash( Encoding.UTF8.GetBytes( ssoKey + uservoiceSubdomain ) ); } byte[] keyBytes = new byte[16]; Array.Copy(keyBytesLong, keyBytes, 16); byte[] textBytes = Encoding.UTF8.GetBytes(userDetails); for (int i = 0; i < 16; i++) { textBytes[i] ^= initVectorBytes[i]; } // Encrypt the string to an array of bytes byte[] encrypted = encryptStringToBytes_AES(textBytes, keyBytes, initVectorBytes); string encoded = Convert.ToBase64String(encrypted); return HttpUtility.UrlEncode(encoded); } static byte[] encryptStringToBytes_AES(byte[] textBytes, byte[] Key, byte[] IV) { // Declare the stream used to encrypt to an in memory // array of bytes and the RijndaelManaged object // used to encrypt the data. using( MemoryStream msEncrypt = new MemoryStream() ) using( RijndaelManaged aesAlg = new RijndaelManaged() ) { // Provide the RijndaelManaged object with the specified key and IV. aesAlg.Mode = CipherMode.CBC; aesAlg.Padding = PaddingMode.PKCS7; aesAlg.KeySize = 128; aesAlg.BlockSize = 128; aesAlg.Key = Key; aesAlg.IV = IV; // Create an encrytor to perform the stream transform. ICryptoTransform encryptor = aesAlg.CreateEncryptor(); // Create the streams used for encryption. using( CryptoStream csEncrypt = new CryptoStream( msEncrypt, encryptor, CryptoStreamMode.Write ) ) { csEncrypt.Write( textBytes, 0, textBytes.Length ); csEncrypt.FlushFinalBlock(); } byte[] encrypted = msEncrypt.ToArray(); // Return the encrypted bytes from the memory stream. return encrypted; } } } }