Home Upgrade Search Memberlist Extras Hacker Tools Award Goals Help Wiki Contact

C# 

[VB.NET & C#] PolyAES - Very high security AES class - Unique output - 256-bit - Salt

Forget using static and UNSECURE IV's and unsecure algorithms.

Features of this AES class:
- Uses always 256-bit AES
- As secure as possible (uses standardized algorithms)
- "Polymorphic" / unique output (CBC cipher mode with random IV)
- Simple to use
- Works with .NET 2.0

Why its secure:
First, it uses AES, algorithm approved by US government to encrypt TOP SECRET information.

Secondly, it uses standard PBKDF2 algorithm to derive encryption key from password key with RANDOM 256-bit salt and RANDOM IV (= dictionary attacks practically impossible).

Salt and IV are automatically stored concatenated after the actual ciphertext (its not a security risk). You dont have to care about them. Decryption function automatically strips them and uses them in encryption. New completely random salt and IV is generated for each crypt automatically.

REMEMBER TO USE ENOUGH BIG PASSWORD/KEY (I SUGGEST AT LEAST 256-BITS = 32 BYTES!)

VB.NET
Code
'
'* Copyright (C) 2011, Dextrey (0xDEADDEAD)
'* Removing this copyright notice is prohibited without permission from author
'* Using this code in your own software product, commercial or not is allowed
'

Imports System.Collections.Generic
Imports System.Text

Namespace DexCrypt
    Class PolyAES

        Const saltSize As Integer = 32

        Private algo As System.Security.Cryptography.SymmetricAlgorithm
        Private rngAlgo As System.Security.Cryptography.RNGCryptoServiceProvider
        Private salt As Byte()
        Public Sub New()
            Me.algo = New System.Security.Cryptography.RijndaelManaged()
            Me.algo.Mode = System.Security.Cryptography.CipherMode.CBC

            Me.rngAlgo = New System.Security.Cryptography.RNGCryptoServiceProvider()
        End Sub

        Private Sub InitializeSecureParameters(key As Byte())
            ' init rijndael IV
            Me.algo.GenerateIV()
            salt = New Byte(saltSize - 1) {}
            rngAlgo.GetBytes(salt)
            Dim pwDeriveAlg As New System.Security.Cryptography.Rfc2898DeriveBytes(key, salt, 2000)
            Me.algo.Key = pwDeriveAlg.GetBytes(32)
        End Sub

        Private Sub LoadSecureParameters(key As Byte(), encIv As Byte(), encSalt As Byte())
            Me.algo.IV = encIv
            Me.salt = encSalt
            Dim pwDeriveAlg As New System.Security.Cryptography.Rfc2898DeriveBytes(key, salt, 2000)
            Me.algo.Key = pwDeriveAlg.GetBytes(32)
        End Sub

        Public Function Encrypt(plainText As String, key As String) As String
            Return Convert.ToBase64String(Me.Encrypt(UnicodeEncoding.UTF8.GetBytes(plainText), UnicodeEncoding.UTF8.GetBytes(key)))
        End Function

        Public Function Decrypt(cipherText As String, key As String) As String
            Return UnicodeEncoding.UTF8.GetString(Me.Decrypt(Convert.FromBase64String(cipherText), UnicodeEncoding.UTF8.GetBytes(key)))
        End Function

        Public Function Encrypt(plainText As Byte(), key As Byte()) As Byte()
            InitializeSecureParameters(key)
            Dim encTransform As System.Security.Cryptography.ICryptoTransform = algo.CreateEncryptor()
            Return ConcatDataToCipherText(ConcatDataToCipherText(encTransform.TransformFinalBlock(plainText, 0, plainText.Length), salt), algo.IV)
        End Function

        Public Function Decrypt(cipherText As Byte(), key As Byte()) As Byte()
            Dim cipherTextWithSalt As Byte() = New Byte(0) {}
            Dim encSalt As Byte() = New Byte(0) {}
            Dim origCipherText As Byte() = New Byte(0) {}
            Dim encIv As Byte() = New Byte(0) {}

            SliceCipherTextIntoParts(cipherText, 16, cipherTextWithSalt, encIv)
            SliceCipherTextIntoParts(cipherTextWithSalt, saltSize, origCipherText, encSalt)
            LoadSecureParameters(key, encIv, encSalt)
            Dim decTransform As System.Security.Cryptography.ICryptoTransform = algo.CreateDecryptor()
            Dim plainText As Byte() = decTransform.TransformFinalBlock(origCipherText, 0, origCipherText.Length)

            Return plainText
        End Function

        Private Function ConcatDataToCipherText(cipherText As Byte(), iv As Byte()) As Byte()
            Dim origLength As Integer = cipherText.Length
            Array.Resize(cipherText, cipherText.Length + iv.Length)
            Buffer.BlockCopy(iv, 0, cipherText, origLength, iv.Length)
            Return cipherText
        End Function
        Private Sub SliceCipherTextIntoParts(cipherText As Byte(), secondPartLen As Integer, ByRef origCipherText As Byte(), ByRef iv As Byte())
            Array.Resize(iv, secondPartLen)
            Buffer.BlockCopy(cipherText, CInt(cipherText.Length - secondPartLen), iv, 0, secondPartLen)
            Array.Resize(origCipherText, CInt(cipherText.Length - secondPartLen))
            Buffer.BlockCopy(cipherText, 0, origCipherText, 0, CInt(cipherText.Length - secondPartLen))
        End Sub
    End Class
End Namespace

C#
Code
/*
* Copyright (C) 2011, Dextrey (0xDEADDEAD)
* Removing this copyright notice is prohibited without permission from author
* Using this code in your own software product, commercial or not is allowed
*/

using System;
using System.Collections.Generic;
using System.Text;

namespace DexCrypt
{
    class PolyAES
    {

  const int saltSize = 32;

  System.Security.Cryptography.SymmetricAlgorithm algo;
  System.Security.Cryptography.RNGCryptoServiceProvider rngAlgo;
  byte[] salt;
  public PolyAES()
  {
    this.algo = new System.Security.Cryptography.RijndaelManaged();
    this.algo.Mode = System.Security.Cryptography.CipherMode.CBC;

    this.rngAlgo = new System.Security.Cryptography.RNGCryptoServiceProvider();
  }

  private void InitializeSecureParameters(byte[] key)
  {
    // init rijndael IV
    this.algo.GenerateIV();
    salt = new byte[saltSize];
    rngAlgo.GetBytes(salt);
    System.Security.Cryptography.Rfc2898DeriveBytes pwDeriveAlg = new System.Security.Cryptography.Rfc2898DeriveBytes(key, salt, 2000);
    this.algo.Key = pwDeriveAlg.GetBytes(32);
  }

  private void LoadSecureParameters(byte[] key, byte[] encIv, byte[] encSalt)
  {
    this.algo.IV = encIv;
    this.salt = encSalt;
    System.Security.Cryptography.Rfc2898DeriveBytes pwDeriveAlg = new System.Security.Cryptography.Rfc2898DeriveBytes(key, salt, 2000);
    this.algo.Key = pwDeriveAlg.GetBytes(32);
  }

  public string Encrypt(string plainText, string key)
  {
    return Convert.ToBase64String(this.Encrypt(UnicodeEncoding.UTF8.GetBytes(plainText), UnicodeEncoding.UTF8.GetBytes(key)));
  }

  public string Decrypt(string cipherText, string key)
  {
    return UnicodeEncoding.UTF8.GetString(this.Decrypt(Convert.FromBase64String(cipherText), UnicodeEncoding.UTF8.GetBytes(key)));
  }

  public byte[] Encrypt(byte[] plainText, byte[] key)
  {
    InitializeSecureParameters(key);
    System.Security.Cryptography.ICryptoTransform encTransform = algo.CreateEncryptor();
    return ConcatDataToCipherText(ConcatDataToCipherText(encTransform.TransformFinalBlock(plainText, 0,  plainText.Length), salt), algo.IV);
  }

  public byte[] Decrypt(byte[] cipherText, byte[] key)
  {
    byte[] cipherTextWithSalt = new byte[1];
    byte[] encSalt = new byte[1];
    byte[] origCipherText = new byte[1];
    byte[] encIv = new byte[1];

    SliceCipherTextIntoParts(cipherText, 16, ref cipherTextWithSalt, ref encIv);
    SliceCipherTextIntoParts(cipherTextWithSalt, saltSize, ref origCipherText, ref encSalt);
    LoadSecureParameters(key, encIv, encSalt);
    System.Security.Cryptography.ICryptoTransform decTransform = algo.CreateDecryptor();
    byte[] plainText = decTransform.TransformFinalBlock(origCipherText, 0, origCipherText.Length);

    return plainText;
  }

  private byte[] ConcatDataToCipherText(byte[] cipherText, byte[] iv)
  {
    int origLength = cipherText.Length;
    Array.Resize(ref cipherText, cipherText.Length + iv.Length);
    Buffer.BlockCopy(iv, 0, cipherText, origLength, iv.Length);
    return cipherText;
  }
  private void SliceCipherTextIntoParts(byte[] cipherText, int secondPartLen, ref byte[] origCipherText, ref byte[] iv)
  {
    Array.Resize(ref iv, secondPartLen);
    Buffer.BlockCopy(cipherText, (int)(cipherText.Length - secondPartLen), iv, 0, secondPartLen);
    Array.Resize(ref origCipherText, (int)(cipherText.Length - secondPartLen));
    Buffer.BlockCopy(cipherText, 0, origCipherText, 0, (int)(cipherText.Length - secondPartLen));
  }
    }
}

Example (note the BAD key):

Code
Dim enc As New PolyAES()
Dim dec As New PolyAES()

Console.WriteLine(enc.Encrypt("Hello, World!", "key123456"))
Console.WriteLine(dec.Decrypt(enc.Encrypt("Hello, World!", "key123456"), "key123456"))

Code
PolyAES enc = new PolyAES();
    PolyAES dec = new PolyAES();

    Console.WriteLine(enc.Encrypt("Hello, World!", "key123456"));
    Console.WriteLine(dec.Decrypt(enc.Encrypt("Hello, World!", "key123456"), "key123456"));
I fucking love you. Seriously.
Nice,thank you for the Code
Stars added :)
I'm glad for positive comments.
✌ yeah, i love your work. and i like the way you code... even if you ignore my pm's 😵
Yeah only one, small function is better for crypters :P
I prefer writing my code in classes (but I still have some structural problems, things could be written better) because its cleaner.
But no offense, very big thanks for posting the functions.
oh god ...
Thank you so much !
This is very nice, good job.
Its quite easy to modify it to use any symmetric cipher which is class inheriting from SymmetricAlgorithm class. I'm gonna update it soon to make it easy to select between ciphers.
wow nice one. can i encrypt and decrypt the strings?

if so how i can protected them and avoid the encrypted to be cracked?
There is direct overload of encrypt function to encrypt strings.
You can encrypt string by:

PolyAES polyAes = new PolyAES();
string encryptedString = polyAes.Encrypt("string to encrypt", "secure encryption key")
polyAes.Decrypt(encryptedString, "secure encryption key")

Have a enough secure key (very long password, or random generated +20 character string) and nobody can crack the string.
If I got this right, when encrypting, you are storing the IV in the encrypted byte array. Later extracting that while decrypting?
Similar to this?

btw, I really like your work :)
The IV is stored in plain format right after the ciphertext ('merged' to it: ciphertext + iv).
And its extracted and then ciphertext is decrypted using it and the key from user.
(Jul 18, 2011 04:14 AM)hgdfhsdgdfgdfh Wrote:  There is direct overload of encrypt function to encrypt strings.
You can encrypt string by:

PolyAES polyAes = new PolyAES();
string encryptedString = polyAes.Encrypt("string to encrypt", "secure encryption key")
polyAes.Decrypt(encryptedString, "secure encryption key")

Have a enough secure key (very long password, or random generated +20 character string) and nobody can crack the string.

thanks. what about if i can decrypt the strings?
With Decrypt function. If your key is good enough nobody can crack the strings without knowing the key.


Possibly Related Threads...
Thread / Author Replies Views Last Post
by HackersApr 14, 2024 12:50 PM 14 659 Apr 14, 2024 12:50 PM
Last Post: Hackers
[C#] by gigajewJul 18, 2021 11:17 AM 26 2,915 Jul 18, 2021 11:17 AM
Last Post: gigajew
[C] by lockheadApr 22, 2021 07:10 AM 0 146 Apr 22, 2021 07:10 AM
Last Post: lockhead