How should I specify a text input and output using this code?
I need to open a file and read its contents (which I know how to do) and then decrypt it using this code.
public string DecryptUsernamePassword(string cipherText)
{
if (string.IsNullOrEmpty(cipherText))
{
return cipherText;
}
byte[] salt = new byte[]
{
(byte)0xc7,
(byte)0x73,
(byte)0x21,
(byte)0x8c,
(byte)0x7e,
(byte)0xc8,
(byte)0xee,
(byte)0x99
};
PKCSKeyGenerator crypto = new PKCSKeyGenerator("PASSWORD HERE", salt, 20, 1);
ICryptoTransform cryptoTransform = crypto.Decryptor;
byte[] cipherBytes = System.Convert.FromBase64String(cipherText);
byte[] clearBytes = cryptoTransform.TransformFinalBlock(cipherBytes, 0, cipherBytes.Length);
return Encoding.UTF8.GetString(clearBytes);
}
cipherText is the encrypted text and clearBytes are the unencrypted bytes but I need to use a textBox with C# forms for input and output.
This is how it needs to work: textBox1.Text (input) -> bytes -> ^above^ string -> bytes -> textBox2.Text (output) Anything works tbh as long as my input is encrypted text and my output is decrypted text.
Based on your comments, assuming I'm still understanding the question properly. Make this into it's own class:
public class UsernameDecryptor
{
public string Decrypt(string cipherText)
{
if (string.IsNullOrEmpty(cipherText))
return cipherText;
byte[] salt = new byte[]
{
(byte)0xc7,
(byte)0x73,
(byte)0x21,
(byte)0x8c,
(byte)0x7e,
(byte)0xc8,
(byte)0xee,
(byte)0x99
};
PKCSKeyGenerator crypto = new PKCSKeyGenerator("PASSWORD HERE", salt, 20, 1);
ICryptoTransform cryptoTransform = crypto.Decryptor;
byte[] cipherBytes = System.Convert.FromBase64String(cipherText);
byte[] clearBytes = cryptoTransform.TransformFinalBlock(cipherBytes, 0, cipherBytes.Length);
return Encoding.UTF8.GetString(clearBytes);
}
}
Then, inside your button handler:
private void button1_Click (object sender, System.EventArgs e)
{
UsernameDecryptor decryptor = new UsernameDecryptor();
string result = decryptor.Decrypt(inputTextBox.Text);
outputTextBox.Text = result;
}
Related
We are using below code to encrypt/decrypt text to store some sensitive information into our database.
public static string Encrypt(string inputText)
{
const string ENCRYPTION_KEY = "MY_KEY";
byte[] SALT = Encoding.ASCII.GetBytes(ENCRYPTION_KEY.Length.ToString());
System.Security.Cryptography.RijndaelManaged rijndaelCipher = null;
byte[] plainText = null;
System.Security.Cryptography.PasswordDeriveBytes SecretKey = null;
try
{
rijndaelCipher = new System.Security.Cryptography.RijndaelManaged();
plainText = Encoding.Unicode.GetBytes(inputText);
SecretKey = new System.Security.Cryptography.PasswordDeriveBytes(ENCRYPTION_KEY, SALT);
using (System.Security.Cryptography.ICryptoTransform encryptor = rijndaelCipher.CreateEncryptor(SecretKey.GetBytes(32), SecretKey.GetBytes(16)))
{
using (System.IO.MemoryStream memoryStream = new System.IO.MemoryStream())
{
using (System.Security.Cryptography.CryptoStream cryptoStream = new System.Security.Cryptography.CryptoStream(memoryStream, encryptor, System.Security.Cryptography.CryptoStreamMode.Write))
{
cryptoStream.Write(plainText, 0, plainText.Length);
cryptoStream.FlushFinalBlock();
return Convert.ToBase64String(memoryStream.ToArray());
}
}
}
}
catch
{
throw;
}
finally
{
rijndaelCipher = null;
plainText = null;
plainText = null;
}
}
public static string Decrypt(string inputText)
{
string ENCRYPTION_KEY = "MY_KEY";
byte[] SALT = Encoding.ASCII.GetBytes(ENCRYPTION_KEY.Length.ToString());
System.Security.Cryptography.RijndaelManaged rijndaelCipher = null;
byte[] encryptedData = null;
byte[] plainText = null;
try
{
rijndaelCipher = new System.Security.Cryptography.RijndaelManaged();
encryptedData = Convert.FromBase64String(inputText);
System.Security.Cryptography.PasswordDeriveBytes secretKey = new System.Security.Cryptography.PasswordDeriveBytes(ENCRYPTION_KEY, SALT);
using (System.Security.Cryptography.ICryptoTransform decryptor = rijndaelCipher.CreateDecryptor(secretKey.GetBytes(32), secretKey.GetBytes(16)))
{
using (System.IO.MemoryStream memoryStream = new System.IO.MemoryStream(encryptedData))
{
using (System.Security.Cryptography.CryptoStream cryptoStream = new System.Security.Cryptography.CryptoStream(memoryStream, decryptor, System.Security.Cryptography.CryptoStreamMode.Read))
{
plainText = new byte[encryptedData.Length];
int decryptedCount = cryptoStream.Read(plainText, 0, plainText.Length);
return Encoding.Unicode.GetString(plainText, 0, decryptedCount);
}
}
}
}
catch
{
return "";
}
finally
{
rijndaelCipher = null;
encryptedData = null;
plainText = null;
}
}
I am not original developer who wrote this code, I need to write some documentation related to security so want to know the exact name of above algorithm. Can someone tell me what is the exact name of above methodology to encrypt/decrypt text. Like MD5, SHA256, AES etc.
I googled a lot but not able to find proper confident answer.
Thanks.
Rijndael is the algorithm that won AES competition, but only for the version with 128 bits of BlockSize. Microsoft doc states that the default value for RijndaelManaged class is 128 so this code uses AES-256-CBC with PKCS7 padding (the key is 32 bytes and no mode is specified).
However this code is very unsecure: you should use a mode such as GCM, or CBC/CTR plus a checksum, and the key should never be derivated from a simple hardcoded ascii string, no matter how long or complex it is, with the salt being a simple copy of it. Finally the IV should be random and saved along the cipherText and not derivated from the key, otherwise attacks common for ECB mode could be applied here as well.
PS: RijndaelManaged is marked as obsolete and Aes or AesCryptoServiceProvider should be used.
I'm creating an C# MVC application by calling Api, Its token encryption method is in PHP i want to convert it to C# code.Can any one help in conversion on below php code to c#?
PHP Code
<?php
//ini_set("display_errors", 1);
//ini_set("display_startup_errors", 1);
function encryptToken($token)
{
$cipher_method = 'aes-128-ctr';
$enc_key = openssl_digest
('*****************************', 'SHA256', TRUE);
$enc_iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length($cipher_method));
$crypted_token = openssl_encrypt($token, $cipher_method, $enc_key, 0, $enc_iv) . "::" . bin2hex($enc_iv);
unset($token, $cipher_method, $enc_key, $enc_iv);
return $crypted_token;
}
function createAccessToken(){
//$date = new DateTime("now", new DateTimeZone('Asia/Kolkata') );
//$now = $date('YmdHis');
$now = date("YmdHis");
$secret ='********************************';
$plainText = $now."::".$secret;
$encrypted = encryptToken($plainText);
return $encrypted;
}
$value="";
if($_POST){
if(isset($_POST['test'])){
$value= createAccessToken();
}
}
?>
So far i tried this much. But the token generated using this C# code will not validate in Api by using the same secret and password.
C# Code
public string GenerateToken()
{
var Date = DateTime.Now.ToString("yyyyMMddHHmmss");
var secret = "#############################";
string plainText = Date + "::" + secret;
var accessToken = EncryptString(plainText);
return accessToken;
}
public string EncryptString(string plainText)
{
try
{
string password = "************************";
// Create sha256 hash
SHA256 mySHA256 = SHA256Managed.Create();
byte[] key = mySHA256.ComputeHash(Encoding.ASCII.GetBytes(password));
// Instantiate a new Aes object to perform string symmetric encryption
Aes encryptor = Aes.Create();
encryptor.Mode = CipherMode.ECB;
encryptor.Padding = PaddingMode.None;
encryptor.BlockSize = 128;
// Create secret IV
var iv = generateIV();
// Set key and IV
byte[] aesKey = new byte[32];
Array.Copy(key, 0, aesKey, 0, 32);
encryptor.Key = aesKey;
encryptor.IV = iv;
// Instantiate a new MemoryStream object to contain the encrypted bytes
MemoryStream memoryStream = new MemoryStream();
// Instantiate a new encryptor from our Aes object
ICryptoTransform aesEncryptor = encryptor.CreateEncryptor();
// Instantiate a new CryptoStream object to process the data and write it to the
// memory stream
CryptoStream cryptoStream = new CryptoStream(memoryStream, aesEncryptor, CryptoStreamMode.Write);
// Convert the plainText string into a byte array
byte[] plainBytes = Encoding.ASCII.GetBytes(plainText);
// Encrypt the input plaintext string
cryptoStream.Write(plainBytes, 0, plainBytes.Length);
// Complete the encryption process
cryptoStream.FlushFinalBlock();
// Convert the encrypted data from a MemoryStream to a byte array
byte[] cipherBytes = memoryStream.ToArray();
// Close both the MemoryStream and the CryptoStream
memoryStream.Close();
cryptoStream.Close();
// Convert the encrypted byte array to a base64 encoded string
string cipherText = Convert.ToBase64String(cipherBytes, 0, cipherBytes.Length) + "::" + ByteArrayToString(iv);
// Return the encrypted data as a string
return cipherText;
}
catch (Exception)
{
throw;
}
}
private static byte[] generateIV()
{
using (RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider())
{
byte[] nonce = new byte[IV_LENGTH];
rng.GetBytes(nonce);
return nonce;
}
}
I have the following code to Encrypt/Decrypt PII data.
public static class Encryption
{
public static readonly int KeyLengthBits = 256; //AES Key Length in bits
public static readonly int SaltLength = 8; //Salt length in bytes
private static readonly RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
private const int PBKDF2IterCount = 1000; // default for Rfc2898DeriveBytes
private const int PBKDF2SubkeyLength = 256 / 8; // 256 bits
private const int SaltSize = 128 / 8; // 128 bits
public static string DecryptString(string ciphertext, string passphrase)
{
var inputs = ciphertext.Split(":".ToCharArray(), 3);
var iv = Convert.FromBase64String(inputs[0]); // Extract the IV
var salt = Convert.FromBase64String(inputs[1]); // Extract the salt
var ciphertextBytes = Convert.FromBase64String(inputs[2]); // Extract the ciphertext
// Derive the key from the supplied passphrase and extracted salt
byte[] key = DeriveKeyFromPassphrase(passphrase, salt);
// Decrypt
byte[] plaintext = DoCryptoOperation(ciphertextBytes, key, iv, false);
// Return the decrypted string
return Encoding.UTF8.GetString(plaintext);
}
public static string EncryptString(string plaintext, string passphrase)
{
var salt = GenerateRandomBytes(SaltLength); // Random salt
var iv = GenerateRandomBytes(16); // AES is always a 128-bit block size
var key = DeriveKeyFromPassphrase(passphrase, salt); // Derive the key from the passphrase
// Encrypt
var ciphertext = DoCryptoOperation(Encoding.UTF8.GetBytes(plaintext), key, iv, true);
// Return the formatted string
return String.Format("{0}:{1}:{2}", Convert.ToBase64String(iv), Convert.ToBase64String(salt), Convert.ToBase64String(ciphertext));
}
private static byte[] DeriveKeyFromPassphrase(string passphrase, byte[] salt, int iterationCount = 2000)
{
var keyDerivationFunction = new Rfc2898DeriveBytes(passphrase, salt, iterationCount); //PBKDF2
return keyDerivationFunction.GetBytes(KeyLengthBits / 8);
}
private static byte[] GenerateRandomBytes(int lengthBytes)
{
var bytes = new byte[lengthBytes];
rng.GetBytes(bytes);
return bytes;
}
// This function does both encryption and decryption, depending on the value of the "encrypt" parameter
private static byte[] DoCryptoOperation(byte[] inputData, byte[] key, byte[] iv, bool encrypt)
{
byte[] output;
using (var aes = new AesCryptoServiceProvider())
using (var ms = new MemoryStream())
{
var cryptoTransform = encrypt ? aes.CreateEncryptor(key, iv) : aes.CreateDecryptor(key, iv);
using (var cs = new CryptoStream(ms, cryptoTransform, CryptoStreamMode.Write))
cs.Write(inputData, 0, inputData.Length);
output = ms.ToArray();
}
return output;
}
}
If I publish this code and encrypt data and then decrypt it, there's no problem. I correctly receive the unencrypted data. If I rebuild my application without making any changes, then publish it again without re-encrypting the data, (it's already encrypted at this point), I'm unable to decrypt it. It just returns the encrypted strings.
Why would re-publishing to the same server to this? Should I be using a different approach? If so, please recommend that different approach.
Thanks
I know this question has been asked before but the answer simply wasn't what I needed. I need to create a password protected text file. I don't mean to encrypt but just create a file with a simple text password. It would also be nice to find out how to open this file in C# as well.
Create a plain-text password protected file and open this file at a later time. All in C#.
Password protecting a text file that is not encrypted is not really possible. However, you can validate if your text file has been modified, so that you are aware it has been altered by someone.
The concept is simple. Use a password to encrypt or obfuscate a hash of the data (text file). You can the later check this hash against the current data and determine whether or not it matches. You will need to store this signature (encrypted hash) somewhere maybe in a file called (textfile.sig).
You can use the SHA1Managed .NET class to create the hash, and the TripleDESCryptoServiceProvider class to encrypt the resulting hash.
something like...
public string GetSignature(string text, string password)
{
byte[] key;
byte[] key2;
GetKeys(password, out key, out key2);
string sig = encryptstring(GetSHA1(text), key, key2);
}
public void GetKeys(string password, out byte[] key, out byte[] key2)
{
byte[] data = StringToByte(password);
SHA1 sha = new SHA1CryptoServiceProvider();
MD5 md5 = new MD5CryptoServiceProvider();
byte[] hash1 = sha.ComputeHash(data);
byte[] hash2 = md5.ComputeHash(data);
// Generate some key data based on the supplied password;
byte[] key = new byte[24];
for (int i = 0; i < 20; i++)
{
key[i] = hash1[i];
}
for (int i = 0; i < 4; i++)
{
key[i + 20] = hash2[i];
}
byte[] key2 = new byte[8];
for (int i = 0; i < 8; i++)
{
key2[i] = hash2[i+4];
}
}
public string GetSHA1(string text)
{
UnicodeEncoding UE = new UnicodeEncoding();
byte[] hashValue;
byte[] message = UE.GetBytes(text);
SHA1Managed hashString = new SHA1Managed();
string hex = "";
hashValue = hashString.ComputeHash(message);
foreach (byte x in hashValue)
{
hex += String.Format("{0:x2}", x);
}
return hex;
}
public string ByteToString(byte[] buff)
{
string sbinary = "";
for (int i = 0; i < buff.Length; i++)
{
sbinary += buff[i].ToString("X2"); // hex format
}
return (sbinary);
}
public string encryptstring(string instr, byte[] key, byte[] key2)
{
TripleDES threedes = new TripleDESCryptoServiceProvider();
threedes.Key = key;
threedes.IV = key2;
ICryptoTransform encryptor = threedes.CreateEncryptor(key, key2);
MemoryStream msEncrypt = new MemoryStream();
CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write);
// Write all data to the crypto stream and flush it.
csEncrypt.Write(StringToByte(instr), 0, StringToByte(instr).Length);
csEncrypt.FlushFinalBlock();
return ByteToString(msEncrypt.ToArray());
}
public string decryptstring(string instr, byte[] key, byte[] key2)
{
if (string.IsNullOrEmpty(instr)) return "";
TripleDES threedes = new TripleDESCryptoServiceProvider();
threedes.Key = key;
threedes.IV = key2;
ICryptoTransform decryptor = threedes.CreateDecryptor(key, key2);
// Now decrypt the previously encrypted message using the decryptor
MemoryStream msDecrypt = new MemoryStream(HexStringToByte(instr));
CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read);
try
{
return ByteToString(csDecrypt);
}
catch (CryptographicException)
{
return "";
}
}
Otherwise, you will if you want to hide the data from people, you need to encrypt the data in the text file. You can do this by calling encryptstring() with the full text data instead of the hash of the data.
Whole point of the question was to not have to encrypt the data manually but let Windows deal with it so I decided to go with Hans Passant's suggestion and simply use a password protected zip file with the needed information (txt files) inside it. This can be easily done with DotNetZip.
I am building a iPhone app which uses c# web services. My c# web services takes user details and validates against my DB and returns xml files.
So Now the issue is how to encrypt user details(username and password are 10chars each) in objective c and decrypt in C#.
I am very new to cryptography, which method is the best. will it be possible to encrypt in Objective c and Decrypt in C#.
thanks..
Thanks for the rapid replies. I appreciate your help. I found a blog which explains my problem. Here is the link for it.
http://dotmac.rationalmind.net/2009/02/aes-interoperability-between-net-and-iphone/
I am implementing it now. I will let you know the status soon.
Thanks a lot..
Happy coding..
On the assumption that you're encrypting this information in order to protect it over the network, the best solution is to connect over SSL. This will address the problem without creating new complexities in the code. SSL handling is generally available in both .NET and Cocoa.
Is there some other reason that you're trying to encrypt this data?
The following is from the The CSharp Cookbook. It is about as straight forwand an example as exists. You would of course have to port the encrypt portion to Objective C, but so long as you used the same Key, it should generate the same result.
You need to use Rijndael cipher which is available here in ObjC compatible code
public static void EncDecString()
{
string encryptedString = CryptoString.Encrypt("MyPassword");
Console.WriteLine("encryptedString: " + encryptedString);
// get the key and IV used so you can decrypt it later
byte [] key = CryptoString.Key;
byte [] IV = CryptoString.IV;
CryptoString.Key = key;
CryptoString.IV = IV;
string decryptedString = CryptoString.Decrypt(encryptedString);
Console.WriteLine("decryptedString: " + decryptedString);
}
public sealed class CryptoString
{
private CryptoString() {}
private static byte[] savedKey = null;
private static byte[] savedIV = null;
public static byte[] Key
{
get { return savedKey; }
set { savedKey = value; }
}
public static byte[] IV
{
get { return savedIV; }
set { savedIV = value; }
}
private static void RdGenerateSecretKey(RijndaelManaged rdProvider)
{
if (savedKey == null)
{
rdProvider.KeySize = 256;
rdProvider.GenerateKey();
savedKey = rdProvider.Key;
}
}
private static void RdGenerateSecretInitVector(RijndaelManaged rdProvider)
{
if (savedIV == null)
{
rdProvider.GenerateIV();
savedIV = rdProvider.IV;
}
}
public static string Encrypt(string originalStr)
{
// Encode data string to be stored in memory
byte[] originalStrAsBytes = Encoding.ASCII.GetBytes(originalStr);
byte[] originalBytes = {};
// Create MemoryStream to contain output
MemoryStream memStream = new MemoryStream(originalStrAsBytes.Length);
RijndaelManaged rijndael = new RijndaelManaged();
// Generate and save secret key and init vector
RdGenerateSecretKey(rijndael);
RdGenerateSecretInitVector(rijndael);
if (savedKey == null || savedIV == null)
{
throw (new NullReferenceException(
"savedKey and savedIV must be non-null."));
}
// Create encryptor, and stream objects
ICryptoTransform rdTransform =
rijndael.CreateEncryptor((byte[])savedKey.Clone(),
(byte[])savedIV.Clone());
CryptoStream cryptoStream = new CryptoStream(memStream, rdTransform,
CryptoStreamMode.Write);
// Write encrypted data to the MemoryStream
cryptoStream.Write(originalStrAsBytes, 0, originalStrAsBytes.Length);
cryptoStream.FlushFinalBlock();
originalBytes = memStream.ToArray();
// Release all resources
memStream.Close();
cryptoStream.Close();
rdTransform.Dispose();
rijndael.Clear();
// Convert encrypted string
string encryptedStr = Convert.ToBase64String(originalBytes);
return (encryptedStr);
}
public static string Decrypt(string encryptedStr)
{
// Unconvert encrypted string
byte[] encryptedStrAsBytes = Convert.FromBase64String(encryptedStr);
byte[] initialText = new Byte[encryptedStrAsBytes.Length];
RijndaelManaged rijndael = new RijndaelManaged();
MemoryStream memStream = new MemoryStream(encryptedStrAsBytes);
if (savedKey == null || savedIV == null)
{
throw (new NullReferenceException(
"savedKey and savedIV must be non-null."));
}
// Create decryptor, and stream objects
ICryptoTransform rdTransform =
rijndael.CreateDecryptor((byte[])savedKey.Clone(),
(byte[])savedIV.Clone());
CryptoStream cryptoStream = new CryptoStream(memStream, rdTransform,
CryptoStreamMode.Read);
// Read in decrypted string as a byte[]
cryptoStream.Read(initialText, 0, initialText.Length);
// Release all resources
memStream.Close();
cryptoStream.Close();
rdTransform.Dispose();
rijndael.Clear();
// Convert byte[] to string
string decryptedStr = Encoding.ASCII.GetString(initialText);
return (decryptedStr);
}
}
I can't speak regarding the Objective C implementation of Rijndael cipher, but I have used this(C#) code for the basis of some production work and it has worked wonderfully.
Your question is very vague, but in short; yes, it is possible. You will need to figure out what the expectations of your cryptography are (high security or high speed?) and then weigh the benefits of various algorthms and their implementation difficulties in Objective-C and C#.
I don't know Objective C, but for the C# decryption, look into the various CryptoServiceProviders in System.Security.Cryptography.
Here is one example I wrote using TripleDES:
public class TripleDES
{
private byte[] mbKey;
private byte[] mbIV;
private TripleDESCryptoServiceProvider tdProvider = new TripleDESCryptoServiceProvider();
private UTF8Encoding UTEncode = new UTF8Encoding();
// Key: **YOUR KEY**
// Project IV: **YOUR IV**
public TripleDES(string strKey, string strIV)
{
mbKey = UTEncode.GetBytes(strKey);
mbIV = UTEncode.GetBytes(strIV);
}
public TripleDES()
{
//
// TODO: Add constructor logic here
//
}
public string EncryptToString(string strInput)
{
return Convert.ToBase64String(this.EncryptToBytes(strInput));
}
public byte[] EncryptToBytes(string strInput)
{
byte[] bInput = UTEncode.GetBytes(strInput);
byte[] bOutput = ProcessInput(bInput, tdProvider.CreateEncryptor(mbKey, mbIV));
return bOutput;
}
public string DecryptToString(string strInput)
{
return UTEncode.GetString(DecryptToBytes(strInput));
}
public byte[] DecryptToBytes(string strInput)
{
byte[] bInput = Convert.FromBase64String(strInput);
byte[] bOutput = ProcessInput(bInput, tdProvider.CreateDecryptor(mbKey, mbIV));
return bOutput;
}
private byte[] ProcessInput(byte[] input, ICryptoTransform ctProcessor)
{
MemoryStream memStream = new MemoryStream();
CryptoStream crpStream = new CryptoStream(memStream, ctProcessor, CryptoStreamMode.Write);
crpStream.Write(input, 0, input.Length);
crpStream.FlushFinalBlock();
memStream.Position = 0;
byte[] output;
output = new byte[memStream.Length];
memStream.Read(output, 0, output.Length);
memStream.Close();
crpStream.Close();
return output;
}
}
}