)>}]
شركة التطبيقات المتكاملة لتصميم وبرمجة البرمجيات الخاصة ش.ش.و.
Integrated Applications Programming Company
Home » Code Library » Encryption (Ia.Cl.Models.Cryptography)

Public general use code classes and xml files that we've compiled and used over the years:

Symmetric Key Algorithm (Rijndael/AES) to encrypt and decrypt data.

    1: using Microsoft.Extensions.Configuration;
    2: using System;
    3: using System.Configuration;
    4: using System.IO;
    5: using System.Security.Cryptography;
    6: using System.Security.Cryptography.X509Certificates;
    7: using System.Text;
    8: using System.Xml;
    9:  
   10: namespace Ia.Cl.Models.Cryptography
   11: {
   12:     ////////////////////////////////////////////////////////////////////////////
   13:  
   14:     /// <summary publish="true">
   15:     /// Symmetric Key Algorithm (Rijndael/AES) to encrypt and decrypt data.
   16:     /// </summary>
   17:     /// <value>
   18:     /// Symmetric Key Algorithm (Rijndael/AES) to encrypt and decrypt data. As long as encryption and decryption routines use the same
   19:     /// parameters to generate the keys, the keys are guaranteed to be the same. The class uses static functions with duplicate code to make it easier to
   20:     /// demonstrate encryption and decryption logic. In a real-life application, this may not be the most efficient way of handling encryption, so - as
   21:     /// soon as you feel comfortable with it - you may want to redesign this class.
   22:     /// 
   23:     /// To create a new certificate (.NET Tools Certificate Creation Tool (Makecert.exe) http://msdn.microsoft.com/en-us/library/bfsktky3(VS.71).aspx)
   24:     /// Do the following:
   25:     /// - "C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin\makecert" -r -pe -n "CN=Test Client Certificate" -b 01/01/2000 -e 01/01/2036 -eku 1.3.6.1.5.5.7.3.1 -ss my -sr CurrentUser -sky exchange -sp "Microsoft RSA SChannel Cryptographic Provider" -sy 12
   26:     /// - Unless, that is, TLS-PSK, the Secure Remote Password (SRP) protocol, or some other protocol is used that can provide strong mutual authentication in the absence of certificates.
   27:     /// - In practice, you will hash the message beforehand (with hash algorithm such as MD5 or SHA1), obtaining the hashed message M1. Then you will encrypt M1 with your private key K0, digitally signing your message, and, finally, you will send your message M, the encrypted hash M1 (the signature) and the public key K1 to your recipient. Your recipient will compute the hash of your message M and will compare it with the decrypted value of M1. If the two hashes matches, the signature is valid.
   28:     /// - Launch the command "certmgr.msc" in Windows Start/Start Search to open the Certificate Manager.
   29:     /// - Double click a certifical file *.pfx to import it into the certificate store and you can use its public keys
   30:     /// For information see:
   31:     /// http://www.codeproject.com/KB/cs/Data_Encryption_Decryptio.aspx
   32:     /// http://www.grimes.demon.co.uk/workshops/secWSSixteen.htm
   33:     /// 
   34:     /// The other party should have a "public key certificate" that I import into my certificate store
   35:     /// 
   36:     /// Import a Certificate:
   37:     /// - You should only import certificates obtained from trusted sources. Importing an unreliable certificate could compromise the security of any system component that uses the imported certificate.
   38:     /// - You can import a certificate into any logical or physical store. In most cases, you will import certificates into the Personal store or the Trusted Root Certification Authorities store, depending on whether the certificate is intended for you or if it is a root CA certificate.
   39:     /// 
   40:     /// http://www.entrust.com/resources/pdf/cryptointro.pdf
   41:     /// - Add certificate name in web.config
   42:     /// </value>
   43:     /// <remarks> 
   44:     /// Copyright � 2001-2024 Jasem Y. Al-Shamlan (info@ia.com.kw), Integrated Applications - Kuwait. All Rights Reserved.
   45:     ///
   46:     /// This library is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by
   47:     /// the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
   48:     ///
   49:     /// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
   50:     /// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   51:     /// 
   52:     /// You should have received a copy of the GNU General Public License along with this library. If not, see http://www.gnu.org/licenses.
   53:     /// 
   54:     /// Copyright notice: This notice may not be removed or altered from any source distribution.
   55:     /// </remarks> 
   56:     public class Encryption
   57:     {
   58:         static string certificateName = System.Configuration.ConfigurationManager.AppSettings["certificateName"].ToString();
   59:  
   60:         ////////////////////////////////////////////////////////////////////////////
   61:  
   62:         /// <summary>
   63:         /// Encryption methods common to most applications - focus is on standard configuration using RSA symetric keys of 1024 bytes or higher.
   64:         /// </summary>
   65:         /// <remark link="http://www.grimes.demon.co.uk/workshops/secWSSixteen.htm"/>
   66:         /// <remark link="http://www.entrust.com/resources/pdf/cryptointro.pdf"/>
   67:         public Encryption() { }
   68:  
   69:         ////////////////////////////////////////////////////////////////////////////
   70:  
   71:         /// <summary>
   72:         /// 
   73:         /// </summary>
   74:         public static class RsaKeys
   75:         {
   76:             ////////////////////////////////////////////////////////////////////////////
   77:  
   78:             /// <summary>
   79:             ///
   80:             /// </summary>
   81:             public static string PublicKey
   82:             {
   83:                 get
   84:                 {
   85:                     string key;
   86:  
   87:                     if (Ia.Cl.Models.ApplicationConfiguration.GetSetting("AppSettings:PublicKey") != null)
   88:                     {
   89:                         key = Ia.Cl.Models.ApplicationConfiguration.GetSetting("AppSettings:PublicKey");
   90:                     }
   91:                     else
   92:                     {
   93:                         throw new Exception("No public-key in appsettings.json file.");
   94:                     }
   95:  
   96:                     return key;
   97:                 }
   98:             }
   99:         }
  100:  
  101:         ////////////////////////////////////////////////////////////////////////////
  102:         ////////////////////////////////////////////////////////////////////////////
  103:  
  104:         /// <summary>
  105:         ///
  106:         /// </summary>
  107:         public static string Sign(string data)
  108:         {
  109:             bool verify;
  110:             byte[] buffer, signature;
  111:             string s;
  112:             X509Certificate2 certificate;
  113:  
  114:             s = string.Empty;
  115:             certificate = null;
  116:  
  117:             certificate = GetCertificate(certificateName);
  118:  
  119:             if (certificate == null) { throw new Exception("No Certificate could be found in name " + certificateName); }
  120:             else
  121:             {
  122:                 if (certificate.HasPrivateKey)
  123:                 {
  124:                     // cast the privateKey object to a RSACryptoServiceProvider object, or, in more elegant way:
  125:                     RSACryptoServiceProvider privateKey = certificate.PrivateKey as RSACryptoServiceProvider;
  126:  
  127:                     // now a signature can be performed. To do so, the SignData method of the privateKey object can be used. It accepts, as input, (1) the data to sign, as array of bytes, and (2) the object that represents the hash algorithm to use:
  128:                     buffer = Encoding.Default.GetBytes(data);
  129:  
  130:                     signature = privateKey.SignData(buffer, new SHA1Managed());
  131:  
  132:                     // signature can also be verified. To do so you must utilize the public key of the certificate.
  133:                     RSACryptoServiceProvider publicKey = certificate.PublicKey.Key as RSACryptoServiceProvider;
  134:                     verify = publicKey.VerifyData(buffer, new SHA1Managed(), signature);
  135:  
  136:                     if (verify) s = Convert.ToBase64String(signature);
  137:                     else s = null;
  138:                 }
  139:                 else
  140:                 {
  141:                     throw new Exception("Certificate used for has no private key.");
  142:                 }
  143:             }
  144:  
  145:             s = "<dataSignature><data>" + data + "</data><signature>" + s + "</signature></dataSignature>";
  146:  
  147:             return s;
  148:         }
  149:  
  150:         ////////////////////////////////////////////////////////////////////////////
  151:  
  152:         /// <summary>
  153:         ///
  154:         /// </summary>
  155:         /// <param name="data"></param>
  156:         /// <param name="recipientCertificate"></param>
  157:         /// <returns></returns>
  158:         public static string Seal(string data, string recipientCertificate)
  159:         {
  160:             string s, cipher, key, iv;
  161:             X509Certificate2 certificate;
  162:  
  163:             s = key = iv = string.Empty;
  164:             certificate = null;
  165:  
  166:             System.Security.Cryptography.Rijndael r = System.Security.Cryptography.Rijndael.Create();
  167:  
  168:             cipher = Ia.Cl.Models.Cryptography.Rijndael.Encrypt(data, r.Key, r.IV);
  169:  
  170:             certificate = GetCertificate(recipientCertificate);
  171:  
  172:             if (certificate == null) { throw new Exception("No Certificate could be found in name " + recipientCertificate); }
  173:             else
  174:             {
  175:                 byte[] cipher_byte;
  176:  
  177:                 using (var rsa = (RSACryptoServiceProvider)certificate.PublicKey.Key)
  178:                 {
  179:                     cipher_byte = rsa.Encrypt(r.Key, false);
  180:                     key = Convert.ToBase64String(cipher_byte);
  181:  
  182:                     cipher_byte = rsa.Encrypt(r.IV, false);
  183:                     iv = Convert.ToBase64String(cipher_byte);
  184:                 }
  185:             }
  186:  
  187:             return s = "<cipherSymmetricKey><cipher>" + cipher + "</cipher><symmetricKey><key>" + key + "</key><iv>" + iv + "</iv></symmetricKey></cipherSymmetricKey>";
  188:         }
  189:  
  190:         ////////////////////////////////////////////////////////////////////////////
  191:  
  192:         /// <summary>
  193:         ///
  194:         /// </summary>
  195:         /// <param name="data"></param>
  196:         /// <returns></returns>
  197:         public static void Deliver(string data)
  198:         {
  199:             // send data 
  200:         }
  201:  
  202:         ////////////////////////////////////////////////////////////////////////////
  203:  
  204:         /// <summary>
  205:         ///
  206:         /// </summary>
  207:         /// <returns></returns>
  208:         public static string Accept()
  209:         {
  210:             // accept data 
  211:             string s;
  212:  
  213:             s = null;
  214:  
  215:             return s;
  216:         }
  217:  
  218:         ////////////////////////////////////////////////////////////////////////////
  219:  
  220:         /// <summary>
  221:         ///
  222:         /// </summary>
  223:         /// <param name="data"></param>
  224:         /// <returns></returns>
  225:         public static string Open(string data)
  226:         {
  227:             byte[] key_, iv_;
  228:             string s, cipher, key, iv;
  229:             XmlDocument xd;
  230:             X509Certificate2 certificate;
  231:  
  232:             key_ = iv_ = null;
  233:             s = string.Empty;
  234:             certificate = null;
  235:  
  236:             certificate = GetCertificate(certificateName);
  237:  
  238:             xd = new XmlDocument();
  239:  
  240:             xd.LoadXml(data);
  241:  
  242:             cipher = xd.SelectSingleNode("cipherSymmetricKey/cipher").InnerText;
  243:             key = xd.SelectSingleNode("cipherSymmetricKey/symmetricKey/key").InnerText;
  244:             iv = xd.SelectSingleNode("cipherSymmetricKey/symmetricKey/iv").InnerText;
  245:  
  246:             if (certificate == null) { throw new Exception("No Certificate could be found in name " + certificateName); }
  247:             else
  248:             {
  249:                 key_ = Convert.FromBase64String(key);
  250:                 iv_ = Convert.FromBase64String(iv);
  251:  
  252:                 using (var rsa = (RSACryptoServiceProvider)certificate.PrivateKey)
  253:                 {
  254:                     key_ = rsa.Decrypt(key_, false);
  255:                     iv_ = rsa.Decrypt(iv_, false);
  256:                 }
  257:             }
  258:  
  259:             System.Security.Cryptography.Rijndael r = System.Security.Cryptography.Rijndael.Create();
  260:  
  261:             s = Ia.Cl.Models.Cryptography.Rijndael.Decrypt(cipher, key_, iv_);
  262:  
  263:             return s;
  264:         }
  265:  
  266:         ////////////////////////////////////////////////////////////////////////////
  267:  
  268:         /// <summary>
  269:         ///
  270:         /// </summary>
  271:         /// <param name="data"></param>
  272:         /// <returns></returns>
  273:         public static string Verify(string data)
  274:         {
  275:             bool verify;
  276:             byte[] buffer, si;
  277:             string s, u, signature;
  278:             XmlDocument xd;
  279:             X509Certificate2 certificate;
  280:  
  281:             s = string.Empty;
  282:             certificate = null;
  283:  
  284:             certificate = GetCertificate(certificateName);
  285:  
  286:             xd = new XmlDocument();
  287:  
  288:             xd.LoadXml(data);
  289:  
  290:             u = xd.SelectSingleNode("dataSignature/data").InnerText;
  291:             signature = xd.SelectSingleNode("dataSignature/signature").InnerText;
  292:  
  293:             if (certificate == null) { throw new Exception("No Certificate could be found in name " + certificateName); }
  294:             else
  295:             {
  296:                 // cast the publicKey object to a RSACryptoServiceProvider object, or, in more elegant way:
  297:                 RSACryptoServiceProvider publiceKey = certificate.PublicKey.Key as RSACryptoServiceProvider;
  298:  
  299:                 // now a signature can be performed. To do so, the SignData method of the privateKey object can be used. It accepts, as input, (1) the data to sign, as array of bytes, and (2) the object that represents the hash algorithm to use:
  300:                 buffer = Encoding.Default.GetBytes(u);
  301:  
  302:                 //si = Encoding.Default.GetBytes(signature);
  303:                 si = Convert.FromBase64String(signature);
  304:  
  305:                 verify = publiceKey.VerifyData(buffer, new SHA1Managed(), si);
  306:             }
  307:  
  308:             s = "<data>" + u + "</data>";
  309:  
  310:             return s;
  311:         }
  312:  
  313:         ////////////////////////////////////////////////////////////////////////////
  314:  
  315:         /// <summary>
  316:         /// Encrypted the specified data.
  317:         /// </summary>
  318:         /// <param name="data">The bytes to encrypt</param>
  319:         /// <returns>Returns the encrypted bytes.</returns>
  320:         public static string Encrypt(string data)
  321:         {
  322:             string s;
  323:             X509Certificate2 certificate;
  324:  
  325:             s = string.Empty;
  326:             certificate = null;
  327:  
  328:             certificate = GetCertificate(certificateName);
  329:  
  330:             if (certificate == null) { throw new Exception("No Certificate could be found in name " + certificateName); }
  331:             else
  332:             {
  333:                 try
  334:                 {
  335:                     string PlainString = data.Trim();
  336:                     byte[] cipherbytes = ASCIIEncoding.ASCII.GetBytes(PlainString);
  337:                     byte[] cipher;
  338:  
  339:                     using (var rsa = (RSACryptoServiceProvider)certificate.PublicKey.Key) cipher = rsa.Encrypt(cipherbytes, false);
  340:  
  341:                     s = Convert.ToBase64String(cipher);
  342:                 }
  343:                 catch (Exception e)
  344:                 {
  345:                     throw e;
  346:                 }
  347:             }
  348:  
  349:             return s;
  350:         }
  351:  
  352:         ////////////////////////////////////////////////////////////////////////////
  353:  
  354:         /// <summary>
  355:         /// Decrypts the bytes specified.
  356:         /// </summary>
  357:         /// <param name="data">The bytes to decrypt</param>
  358:         /// <returns>Returns the decrypted bytes.</returns>
  359:         public static string Decrypt(string data)
  360:         {
  361:             string s;
  362:             X509Certificate2 certificate;
  363:  
  364:             s = string.Empty;
  365:             certificate = null;
  366:  
  367:             certificate = GetCertificate(certificateName);
  368:  
  369:             if (certificate == null) { throw new Exception("No Certificate could be found in name " + certificateName); }
  370:             else
  371:             {
  372:                 try
  373:                 {
  374:                     byte[] cipherbytes = Convert.FromBase64String(data);
  375:  
  376:                     if (certificate.HasPrivateKey)
  377:                     {
  378:                         byte[] plainbytes;
  379:  
  380:                         using (RSACryptoServiceProvider rsa = (RSACryptoServiceProvider)certificate.PrivateKey) plainbytes = rsa.Decrypt(cipherbytes, false);
  381:  
  382:                         System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
  383:  
  384:                         s = enc.GetString(plainbytes);
  385:                     }
  386:                     else
  387:                     {
  388:                         throw new Exception("Certificate used for has no private key.");
  389:                     }
  390:                 }
  391:                 catch (Exception e)
  392:                 {
  393:                     throw e;
  394:                 }
  395:             }
  396:  
  397:             return s;
  398:         }
  399:  
  400:         ////////////////////////////////////////////////////////////////////////////
  401:  
  402:         /// <summary>
  403:         /// Return the certificate in X509Certificate2 format from its string name
  404:         /// </summary>
  405:         /// <param name="name">Certificate name</param>
  406:         /// <returns>Certificate</returns>
  407:         private static X509Certificate2 GetCertificate(string name)
  408:         {
  409:             X509Store store;
  410:             X509Certificate2 certificate;
  411:  
  412:             certificate = null;
  413:  
  414:             store = new X509Store(StoreName.My);
  415:             store.Open(OpenFlags.ReadWrite);
  416:  
  417:             if (name.Length > 0)
  418:             {
  419:                 foreach (X509Certificate2 cert in store.Certificates)
  420:                 {
  421:                     if (cert.SubjectName.Name.Contains(name))
  422:                     {
  423:                         certificate = cert;
  424:                         break;
  425:                     }
  426:                 }
  427:             }
  428:             else
  429:             {
  430:                 certificate = store.Certificates[0];
  431:             }
  432:  
  433:             return certificate;
  434:         }
  435:  
  436:         ////////////////////////////////////////////////////////////////////////////
  437:         ////////////////////////////////////////////////////////////////////////////
  438:     }
  439:  
  440:     ////////////////////////////////////////////////////////////////////////////
  441:     ////////////////////////////////////////////////////////////////////////////
  442:  
  443:     /// <summary>
  444:     /// This class uses a symmetric key algorithm (Rijndael/AES) to encrypt and decrypt data. As long as encryption and decryption routines use the same
  445:     /// parameters to generate the keys, the keys are guaranteed to be the same. The class uses static functions with duplicate code to make it easier to
  446:     /// demonstrate encryption and decryption logic. In a real-life application, this may not be the most efficient way of handling encryption, so - as
  447:     /// soon as you feel comfortable with it - you may want to redesign this class.
  448:     /// </summary>
  449:     public class Rijndael
  450:     {
  451:         ////////////////////////////////////////////////////////////////////////////
  452:         ////////////////////////////////////////////////////////////////////////////
  453:  
  454:         /// <summary>
  455:         /// Encrypts specified plaintext using Rijndael symmetric key algorithm
  456:         /// and returns a base64-encoded result.
  457:         /// </summary>
  458:         /// <param name="plainText">
  459:         /// Plaintext value to be encrypted.
  460:         /// </param>
  461:         /// <param name="initVectorBytes">
  462:         /// Initialization vector (or IV). This value is required to encrypt the first block of plaintext data. For RijndaelManaged class IV must be exactly 16 ASCII characters long.
  463:         /// </param>
  464:         /// <param name="keyBytes"></param>
  465:         /// <returns>
  466:         /// Encrypted value formatted as a base64-encoded string.
  467:         /// </returns>
  468:         public static string Encrypt(string plainText, byte[] keyBytes, byte[] initVectorBytes)
  469:         {
  470:             // convert our plaintext into a byte array. Let us assume that plaintext contains UTF8-encoded characters.
  471:             byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText);
  472:             string cipher;
  473:  
  474:             // create uninitialized Rijndael encryption object.
  475:             RijndaelManaged symmetricKey = new RijndaelManaged();
  476:  
  477:             // It is reasonable to set encryption mode to Cipher Block Chaining (CBC). Use default options for other symmetric key parameters.
  478:             symmetricKey.Mode = CipherMode.CBC;
  479:  
  480:             // Generate encryptor from the existing key bytes and initialization vector. Key size will be defined based on the number of the key bytes.
  481:             ICryptoTransform encryptor = symmetricKey.CreateEncryptor(keyBytes, initVectorBytes);
  482:  
  483:             // Define memory stream which will be used to hold encrypted data.
  484:             using (MemoryStream memoryStream = new MemoryStream())
  485:             {
  486:                 // Define cryptographic stream (always use Write mode for encryption).
  487:                 using (CryptoStream cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
  488:                 {
  489:                     // Start encrypting.
  490:                     cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
  491:  
  492:                     // Finish encrypting.
  493:                     cryptoStream.FlushFinalBlock();
  494:  
  495:                     // Convert our encrypted data from a memory stream into a byte array.
  496:                     byte[] cipherTextBytes = memoryStream.ToArray();
  497:  
  498:                     // Convert encrypted data into a base64-encoded string.
  499:                     cipher = Convert.ToBase64String(cipherTextBytes);
  500:  
  501:                     //cryptoStream.Close();
  502:                 }
  503:  
  504:                 //memoryStream.Close();
  505:             }
  506:  
  507:             // Return encrypted string.
  508:             return cipher;
  509:         }
  510:  
  511:         ////////////////////////////////////////////////////////////////////////////
  512:  
  513:         /// <summary>
  514:         /// Decrypts specified ciphertext using Rijndael symmetric key algorithm.
  515:         /// </summary>
  516:         /// <param name="cipher">
  517:         /// Base64-formatted ciphertext value.
  518:         /// </param>
  519:         /// <param name="initVectorBytes">
  520:         /// Initialization vector (or IV). This value is required to encrypt the first block of plaintext data. For RijndaelManaged class IV must be exactly 16 ASCII characters long.
  521:         /// </param>
  522:         /// <param name="keyBytes"></param>
  523:         /// <returns>
  524:         /// Decrypted string value.
  525:         /// </returns>
  526:         /// <remarks> 
  527:         /// Most of the logic in this function is similar to the Encrypt logic. In order for decryption to work, all parameters of this function
  528:         /// - except cipher value - must match the corresponding parameters of the Encrypt function which was called to generate the ciphertext.
  529:         /// </remarks>
  530:         public static string Decrypt(string cipher, byte[] keyBytes, byte[] initVectorBytes)
  531:         {
  532:             // Convert our ciphertext into a byte array.
  533:             byte[] cipherTextBytes = Convert.FromBase64String(cipher);
  534:             string plainText;
  535:  
  536:             // Create uninitialized Rijndael encryption object.
  537:             RijndaelManaged symmetricKey = new RijndaelManaged();
  538:  
  539:             // It is reasonable to set encryption mode to Cipher Block Chaining (CBC). Use default options for other symmetric key parameters.
  540:             symmetricKey.Mode = CipherMode.CBC;
  541:  
  542:             // Generate decryptor from the existing key bytes and initialization vector. Key size will be defined based on the number of the key bytes.
  543:             ICryptoTransform decryptor = symmetricKey.CreateDecryptor(keyBytes, initVectorBytes);
  544:  
  545:             // Define memory stream which will be used to hold encrypted data.
  546:             using (MemoryStream memoryStream = new MemoryStream(cipherTextBytes))
  547:             {
  548:                 // Define cryptographic stream (always use Read mode for encryption).
  549:                 using (CryptoStream cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
  550:                 {
  551:                     // Since at this point we don't know what the size of decrypted data will be, allocate the buffer long enough to hold ciphertext; plaintext is never longer than ciphertext.
  552:                     byte[] plainTextBytes = new byte[cipherTextBytes.Length];
  553:  
  554:                     // Start decrypting.
  555:                     int decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length);
  556:  
  557:                     // Convert decrypted data into a string. Let us assume that the original plaintext string was UTF8-encoded.
  558:                     plainText = Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount);
  559:  
  560:                     // Close both streams.
  561:                     //cryptoStream.Close();
  562:                 }
  563:  
  564:                 //memoryStream.Close();
  565:             }
  566:  
  567:             // Return decrypted string.   
  568:             return plainText;
  569:         }
  570:  
  571:         /*
  572:         ////////////////////////////////////////////////////////////////////////////
  573: 
  574:         /// <summary>
  575:         ///
  576:         /// </summary>
  577:         /// <returns></returns>
  578:         public static byte[] Password()
  579:         {
  580:             /// <param name="passPhrase">
  581:             /// Passphrase from which a pseudo-random password will be derived. The
  582:             /// derived password will be used to generate the encryption key.
  583:             /// Passphrase can be any string. In this example we assume that this
  584:             /// passphrase is an ASCII string.
  585:             /// </param>
  586:             /// <param name="saltValue">
  587:             /// Salt value used along with passphrase to generate password. Salt can
  588:             /// be any string. In this example we assume that salt is an ASCII string.
  589:             /// </param>
  590:             /// <param name="hashAlgorithm">
  591:             /// Hash algorithm used to generate password. Allowed values are: "MD5" and
  592:             /// "SHA1". SHA1 hashes are a bit slower, but more secure than MD5 hashes.
  593:             /// </param>
  594:             /// <param name="passwordIterations">
  595:             /// Number of iterations used to generate password. One or two iterations
  596:             /// should be enough.
  597:             /// </param>
  598:             /// <param name="keySize">
  599:             /// Size of encryption key in bits. Allowed values are: 128, 192, and 256.
  600:             /// Longer keys are more secure than shorter keys.
  601:             /// </param>
  602: 
  603:             string passPhrase = "*";        // can be any string
  604:             string saltValue = "*";        // can be any string
  605:             string hashAlgorithm = "SHA1";             // can be "MD5"
  606:             int passwordIterations = 2;                  // can be any number
  607:             int keySize = 256;                // can be 192 or 128
  608: 
  609:             // Convert strings defining encryption key characteristics into byte
  610:             // arrays. Let us assume that strings only contain ASCII codes.
  611:             // If strings include Unicode characters, use Unicode, UTF7, or UTF8
  612:             // encoding.
  613:             byte[] saltValueBytes = Encoding.ASCII.GetBytes(saltValue);
  614: 
  615:             // First, we must create a password, from which the key will be 
  616:             // derived. This password will be generated from the specified 
  617:             // passphrase and salt value. The password will be created using
  618:             // the specified hash algorithm. Password creation can be done in
  619:             // several iterations.
  620:             PasswordDeriveBytes password = new PasswordDeriveBytes(passPhrase, saltValueBytes, hashAlgorithm, passwordIterations);
  621: 
  622:             // Use the password to generate pseudo-random bytes for the encryption
  623:             // key. Specify the size of the key in bytes (instead of bits).
  624:             byte[] keyBytes = password.GetBytes(keySize / 8);
  625: 
  626:             return keyBytes;
  627:         }
  628:         */
  629:  
  630:         ////////////////////////////////////////////////////////////////////////////
  631:         ////////////////////////////////////////////////////////////////////////////
  632:     }
  633:  
  634:     ////////////////////////////////////////////////////////////////////////////
  635:     ////////////////////////////////////////////////////////////////////////////
  636:  
  637:     /// <summary>
  638:     /// 
  639:     /// </summary>
  640:     public class Md5
  641:     {
  642:         ////////////////////////////////////////////////////////////////////////////
  643:  
  644:         /// <summary>
  645:         /// 
  646:         /// </summary>
  647:         public static string Hash(string text)
  648:         {
  649:             // hash an input string and return the hash as a 32 character hexadecimal string
  650:  
  651:             byte[] data;
  652:             StringBuilder sb;
  653:             MD5 md5;
  654:  
  655:             sb = new StringBuilder();
  656:             md5 = MD5.Create();
  657:  
  658:             // convert the input string to a byte array and compute the hash
  659:             data = md5.ComputeHash(Encoding.Default.GetBytes(text));
  660:  
  661:             // loop through each byte of the hashed data and format each one as a hexadecimal string
  662:             for (int i = 0; i < data.Length; i++) sb.Append(data[i].ToString("x2"));
  663:  
  664:             return sb.ToString();
  665:         }
  666:  
  667:         ////////////////////////////////////////////////////////////////////////////
  668:         ////////////////////////////////////////////////////////////////////////////
  669:     }
  670:  
  671:     ////////////////////////////////////////////////////////////////////////////
  672:     ////////////////////////////////////////////////////////////////////////////
  673:  
  674:     /// <summary>
  675:     /// 
  676:     /// </summary>
  677:     public class ApiKey
  678:     {
  679:         ////////////////////////////////////////////////////////////////////////////
  680:  
  681:         /// <summary>
  682:         /// https://classichelp.kayako.com/hc/en-us/articles/360006459899-Code-Snippets-for-Generating-an-API-Signature#h_15e873c0-f033-44fe-9648-cfe813cc8edb
  683:         /// </summary>
  684:         public static string Generate()
  685:         {
  686:             var apiKey = "apikey";
  687:             var secretKey = "secretkey";
  688:  
  689:             // Generate a new globally unique identifier for the salt
  690:             var salt = System.Guid.NewGuid().ToString();
  691:  
  692:             // Initialize the keyed hash object using the secret key as the key
  693:             HMACSHA256 hashObject = new HMACSHA256(Encoding.UTF8.GetBytes(secretKey));
  694:  
  695:             // Computes the signature by hashing the salt with the secret key as the key
  696:             var signature = hashObject.ComputeHash(Encoding.UTF8.GetBytes(salt));
  697:  
  698:             // Base 64 Encode
  699:             var encodedSignature = Convert.ToBase64String(signature);
  700:  
  701:             // URLEncode
  702:             //encodedSignature = System.Web.HttpUtility.UrlEncode(encodedSignature);
  703:  
  704:             return encodedSignature;
  705:         }
  706:     }
  707:  
  708:     ////////////////////////////////////////////////////////////////////////////
  709:     ////////////////////////////////////////////////////////////////////////////
  710: }
  711: