NaCL sealed box on different platforms - c#

There is tweetnacl-sealedbox-js for node.js
For example we can encrypt some data
const key = crypto.pseudoRandomBytes(32);
const publicKey = 'ed9f2af89336b2ff5960634fafb401ca36644cad61cb6a1daafdda0c74ef4636';
const encryptedKey = seal(key, Buffer.from(publicKey, 'hex'));
But is there similar library for C# ? I'm trying to use libsodium-net but am not completely sure that this is correct
For example
byte[] randKey = new byte[32];
Random.NextBytes(randKey);
string publicKey = "ed9f2af89336b2ff5960634fafb401ca36644cad61cb6a1daafdda0c74ef4636";
byte[] encryptedKey = SealedPublicKeyBox.Create(randKey, HexToByte(publicKey));
public static byte [] HexToByte(string hexStr)
{
byte[] bArray = new byte[hexStr.Length / 2];
for (int i = 0; i < (hexStr.Length / 2); i++)
{
byte firstNibble = Byte.Parse(hexStr.Substring((2 * i), 1),
System.Globalization.NumberStyles.HexNumber); // [x,y)
byte secondNibble = Byte.Parse(hexStr.Substring((2 * i) + 1, 1),
System.Globalization.NumberStyles.HexNumber);
int finalByte = (secondNibble) | (firstNibble << 4);
bArray[i] = (byte)finalByte;
}
return bArray;
}
Does anybody know can the owner of private key decrypt both messages? or c# code is not the same action?

SO I make some tests:
run var keyPair = tweetnacl.box.keyPair() at node.js and convert to base64 strings public key and secret key.
var pubKey = Buffer.from('Uv4bICdcUlIO+Z9YsLLg9EGaLPy/M7oTBVZJn2B7XhU=', 'base64');
var secKey = Buffer.from('fEAUUQ+axuD3NkOr+a59ZtsVurZPTa4Ee8ULoNr3WS0=', 'base64');
try to encrypt message via c# and libsodium-net like that:
string mes = "i want to believe";
string pKey = "Uv4bICdcUlIO+Z9YsLLg9EGaLPy/M7oTBVZJn2B7XhU=";
byte [] enc = Sodium.SealedPublicKeyBox.Create(mes, Convert.FromBase64String(pKey));
return Convert.ToBase64String(enc);
and try to decrypt message via node.js
var msg = Buffer.from('uW+5ecQhzKKx++uRYcbCu2nUVNIqToWTSjVB7UmdDCeJn9Buf3UWFu5kRfIGIxMJYdVeTFijdvJhlHR0VBd5HnE=', 'base64');
var result = sealedbox.open(msg, pubKey, secKey);
console.log(Buffer.from(result).toString());
and got my message in log.
so I found out that these libraries are mutually compatible.

Related

AES Encryption in C# and Decryption in JS using crypto-js

UseCase:
I am developing a service that is in C# and I have to send an encrypted string to a different system that is already coded in JS using CryptoJS which will be decrypting the string I am going to be sending.
The receiving system is not going to make any changes to its implementation. They have shared the JS code they are using to DECRYPT along with the required credentials that I would need for my encryption.
JS code of both Encrypt and Decrypt from the receiver
var message = "hello world!!!";
function generateKey(salt, passPhrase, keySize, iterationCount) {
const key = CryptoJS.PBKDF2(passPhrase, CryptoJS.enc.Hex.parse(salt), {
keySize: keySize / 32,
iterations: iterationCount
});
return key;
}
function Encrypt(cipherText) {
const salt = "DUMMYSALT-VALUE-of-Size-32CHARACTERS";
const iv ="DUMMYIV-VALUE-of-Size-32CHARACTERS";
const passPhrase = "SomeSecretPassPhrase";
const keySize = 128
const iterationCount = 1
const key = generateKey(salt, passPhrase, keySize, iterationCount);
const encrypted = CryptoJS.AES.encrypt(cipherText, key, {
iv: CryptoJS.enc.Hex.parse(iv)
});
return encrypted.ciphertext.toString();
}
function Decrypt(cipherText, pass = "SomeSecretPassPhrase") {
const salt = "DUMMYSALT-VALUE-of-Size-32CHARACTERS";
const iv ="DUMMYIV-VALUE-of-Size-32CHARACTERS";
const passPhrase = "SomeSecretPassPhrase";
const keySize = 128
const iterationCount = 1
const key = generateKey(salt, passPhrase, keySize, iterationCount);
const cipherParams = CryptoJS.lib.CipherParams.create({
ciphertext: CryptoJS.enc.Hex.parse(cipherText)
});
const decrypted = CryptoJS.AES.decrypt(cipherParams, key, {
iv: CryptoJS.enc.Hex.parse(iv)
});
return decrypted.toString(CryptoJS.enc.Utf8);
}
var encrypted = Encrypt(message);
//equivalent to CryptoJS.AES.encrypt(CryptoJS.enc.Utf8.parse(message), key);
var decrypted = Decrypt(encrypted);
$('#1').text("Encrypted: "+encrypted.toString(CryptoJS.enc.Utf8));
$('#2').text("Decrypted: "+decrypted.toString(CryptoJS.enc.Utf8));
Output
Encrypted: 24a935f11a3e0b35dd6604cd7dbee292
Decrypted: hello world!!!
Question: While I try to port this over the C# and try to encrypt a string using the below, my encrypted value is different and also the JS code is unable to decrypt it.
my code to encrypt:
var MyKey = GenerateKey("DUMMYSALT-VALUE-of-Size-32CHARACTERS", "SomeSecretPassPhrase");
var EncryptedString = EncryptString(MyKey, "hello world!!!");
public byte[] GenerateKey(string saltVal, string passphrase)
{
byte[] salt = ConvertHexStringToByteArray("DUMMYSALT-VALUE-of-Size-32CHARACTERS");
int iterations = 1;
var rfc2898 = new Rfc2898DeriveBytes(passphrase, salt, iterations);
byte[] key = rfc2898.GetBytes(16);
return key;
}
public string EncryptString(byte[] key, string stringToEncrypt )
{
AesManaged aesCipher = new AesManaged();
aesCipher.KeySize = 128;
aesCipher.BlockSize = 128;
aesCipher.Mode = CipherMode.CBC;
aesCipher.Padding = PaddingMode.PKCS7;
aesCipher.Key = key;
aesCipher.IV = ConvertHexStringToByteArray("DUMMYPRESETIV-VALUE-of-Size-32CHARACTERS");
byte[] b = System.Text.Encoding.UTF8.GetBytes(stringToEncrypt);
ICryptoTransform encryptTransform = aesCipher.CreateEncryptor();
byte[] ctext = encryptTransform.TransformFinalBlock(b, 0, b.Length);
System.Console.WriteLine("IV:" + Convert.ToBase64String(aesCipher.IV));
System.Console.WriteLine("Cipher text: " + Convert.ToBase64String(ctext));
return Convert.ToBase64String(ctext);
}
public byte[] ConvertHexStringToByteArray(string hexString)
{
int NumberChars = hexString.Length;
byte[] bytes = new byte[NumberChars / 2];
for (int i = 0; i < NumberChars; i += 2)
bytes[i / 2] = Convert.ToByte(hexString.Substring(i, 2), 16);
return bytes;
}
I am not sure if am doing the correct equivalent of the JS method CryptoJS.enc.Hex.parse()
,

c# Bouncy Castle Blowfish Decryption - Pad block corrupted

I am trying to decrypt a blowfish encrypted string with Bouncycastle in C#.
I am able to easily encrypt and decrypt my own string but, unfortunately, I have to decrypt a string that is generated by another system.
I AM able to recreate that same string with C# / Bouncycastle using the following but I have yet to decrypt it successfully.
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto.Paddings;
using Org.BouncyCastle.Crypto.Parameters;
...
static readonly Encoding Encoding = Encoding.UTF8;
public string BlowfishEncrypt(string strValue, string key)
{
try
{
BlowfishEngine engine = new BlowfishEngine();
PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(engine);
KeyParameter keyBytes = new KeyParameter(Encoding.GetBytes(key));
cipher.Init(true, keyBytes);
byte[] inB = Encoding.GetBytes(strValue);
byte[] outB = new byte[cipher.GetOutputSize(inB.Length)];
int len1 = cipher.ProcessBytes(inB, 0, inB.Length, outB, 0);
cipher.DoFinal(outB, len1);
return BitConverter.ToString(outB).Replace("-", "");
}
catch (Exception)
{
return "";
}
}
Below is what I have for decryption at the moment. The line that fails with error "pad block corrupted" is cipher.DoFinal(out2, len2);
public string BlowfishDecrypt(string name, string keyString)
{
BlowfishEngine engine = new BlowfishEngine();
PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(engine);
StringBuilder result = new StringBuilder();
cipher.Init(false, new KeyParameter(Encoding.GetBytes(keyString)));
byte[] out1 = Convert.FromBase64String(name);
byte[] out2 = new byte[cipher.GetOutputSize(out1.Length)];
int len2 = cipher.ProcessBytes(out1, 0, out1.Length, out2, 0);
cipher.DoFinal(out2, len2); //Pad block corrupted error happens here
String s2 = BitConverter.ToString(out2);
for (int i = 0; i < s2.Length; i++) {
char c = s2[i];
if (c != 0) {
result.Append(c.ToString());
}
}
return result.ToString();
}
Any idea what I might be doing wrong in BlowfishDecrypt()?
Note:
I converted the above (encrypt and decrypt) from a bouncycastle Java example I found somewhere; the encrypt works. The only difference I can see is that the Java example uses a StringBuffer where I use a StringBuilder.
Thank you, Artjom B!
byte[] out1 = Convert.FromBase64String(name);
Should have been
byte[] out1 = Hex.Decode(name);
From there, all I had to do was convert the Hex to a string.

Encryption String with Session Key in c#

I want to encrypt String with SessionKey. Below is sample code I am using, but I am not getting the correct encrypted answer.
string = test;
SessionKey = "ThisIsASecretKey";
For encryption, I am using the method below:
byte[] array = Encoding.ASCII.GetBytes("ThisIsASecretKey");
byte[] array1 = Encoding.ASCII.GetBytes("test");
byte[] reult = encryptUsingSessionKey(array, array1);
public byte[] encryptUsingSessionKey(byte[] skey,byte[] data)
{
Org.BouncyCastle.Crypto.Paddings.PaddedBufferedBlockCipher cipher = new Org.BouncyCastle.Crypto.Paddings.PaddedBufferedBlockCipher(new AesEngine(), new Pkcs7Padding());
cipher.Init(true, new Org.BouncyCastle.Crypto.Parameters.KeyParameter(skey));
int outputSize = cipher.GetOutputSize(data.Length);
byte[] tempOP = new byte[outputSize];
int processLen = cipher.ProcessBytes(data, 0, data.Length, tempOP, 0);
int outputLen = cipher.DoFinal(tempOP, processLen);
byte[] result = new byte[processLen + outputLen];
tempOP.CopyTo(result, 0);
// tempOP.CopyTo(tempOP,0,result,0,result.Length);
return result;
}
After encryption, I am getting
jZî|ðçê`u0aC
but the correct answer would be
ƒ_jZî|ðç_ê‹\`u0aC

SSCrypto from Objective C to C#

I am trying to encrypt below base64 string in objective c .. Now i need to decrypt the output of below code in C# ... Please advice simplest way as i don't want to install any libs at server.
Please advice how can convert encripted string back to base64 using C# .
Thanks
My Objective c Code for encripting the base 64
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
SSCrypto *crypto;
NSString *password =#"abcdefghijklmnoqrstuvwzyzabcdefghijklmnopqrstuvwzyzabcdefghijklmnopqrstuvwzyzabcdefghijklmnopqrstuvwzyzabcdefghijklmnopqrstuvwzyzabcdefghijklmnopqrstuvwzyzabcdefghijklmnopqrstuvwzyzabcdefghijklmnopqrstuvwzyzabcdefghijklmnoqrstuvwzyzabcdefghijklmnopqrstuvwzyzabcdefghijklmnopqrstuvwzyzabcdefghijklmnopqrstuvwzyzabcdefghijklmnopqrstuvwzyzabcdefghijklmnopqrstuvwzyzabcdefghijklmnopqrstuvwzyzabcdefghijklmnopqrstuvwzyz";
NSData *seedData1 = [password dataUsingEncoding:NSUTF8StringEncoding];
crypto = [[SSCrypto alloc] initWithSymmetricKey:seedData1];
NSString *base64String = #"SUkqAAgAAAARAP4ABAABAAAAAAAAAAABAwABAAAAsAQAAAEBAwABAAAAEAIAAAIBAwABAAAAAQAAAAMBAwABAAAABAAAAAYBAwABAAAAAAAAAAoBAwABAAAAAQAAABEBBAABAAAACgEAABIBAwABAAAAAQAAABUBAwABAAAAAQAAABYBAwABAAAAEAIAABcBBAABAAAA3yUAABoBBQABAAAA2gAAABsBBQABAAAA4gAAACUBBAABAAAAAAAAACgBAwABAAAAAgAAADEBAgAgAAAA6gAAAAAAAADIAAAAAQAAAMgAAAABAAAAQ29tcHJlc3NlZCB3aXRoIFBBTklOSSBJbWFnZSsAAAAmoy1xRBcev/r/LSUkbRxE+cRxGpEdF0Rw2EcNhHDIBcufR2+R0XZJjI6OIj5HjCPRHR9F0R8wCmRwXI6I+eROjiNxpEdkdEdl2R8ujTMMuy+R0R8j5HZvNo2yOzcXyOiPkdFzLsjxHGRwbC5lwJQaQRDaCchYbAxEREREREREREREREREREREREREREREREREI0BuRww+RIyPFw2MSnIccp0yY58fgxZ5EcKaVhJdx//pL0OQwm5EA///WlgnWSAb/+q9KEgt4X+961qgtKkZJCMH/XlnojiSvNBUkmSCPZBiQlT//iR7pdK0tgnwzep3zv//DLtrqmuLDodf/X7w2lasnCq7CWPf/0l2a6sIIRSVjoLFf9/3sMJ+jrkIjeTonRHRtE6N5A86ohEQtF0d6Ijol0IiIiIiIiIiIi0IiIiIiOIiIiIiIiIiIiIiIiIiIiIgwjtb8tBIhXABABA==";
[crypto setClearTextWithString:base64String];
NSData *cipherText = [crypto encrypt:#"aes256"];
NSLog(#"Cipher text: '%#' using %#", [cipherText encodeBase64WithNewlines:NO], #"aes256");
NSLog(#" ");
[ pool release];
Below is my C# code for Decryption
public static string DecryptString(string base64StringToDecrypt, string passphrase)
{
//Set up the encryption objects
using (AesCryptoServiceProvider acsp = GetProvider(Encoding.Default.GetBytes(passphrase)))
{
byte[] RawBytes = Convert.FromBase64String(base64StringToDecrypt);
ICryptoTransform ictD = acsp.CreateDecryptor();
// TripleDES.
//RawBytes now contains original byte array, still in Encrypted state
//Decrypt into stream
MemoryStream msD = new MemoryStream(RawBytes, 0, RawBytes.Length);
CryptoStream csD = new CryptoStream(msD, ictD, CryptoStreamMode.Read);
//csD now contains original byte array, fully decrypted
//return the content of msD as a regular string
return (new StreamReader(csD)).ReadToEnd();
}
private static AesCryptoServiceProvider GetProvider(byte[] key)
{
AesCryptoServiceProvider result = new AesCryptoServiceProvider();
result.BlockSize = 128;
result.KeySize = 128;
result.Mode = CipherMode.CBC;
result.Padding = PaddingMode.PKCS7;
result.GenerateIV();
result.IV = new byte[] {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
byte[] RealKey = GetKey(key, result);
result.Key = RealKey;
// result.IV = RealKey;
return result;
}
private static byte[] GetKey(byte[] suggestedKey, SymmetricAlgorithm p)
{
byte[] kRaw = suggestedKey;
List<byte> kList = new List<byte>();
for (int i = 0; i < p.LegalKeySizes[0].MinSize; i += 8)
{
kList.Add(kRaw[(i / 8) % kRaw.Length]);
}
byte[] k = kList.ToArray();
return k;
}
Please advice if anything is missing or if i have done something gross wrong ..
I have lost more than 2 days in searching.
You can do this easily with the AesManaged class. See:
http://msdn.microsoft.com/en-us/library/system.security.cryptography.aesmanaged.aspx

need a help in order to Encrypt/decrypt file using bouncy castle in c#

please help;
i have creted a server application that generate a x.509v3 certificates. than, i export a publique and private key in .txt file ( format hex, or pem) ;
i must now encrypt files in another client application, my problem is that i can't do this using a public key directly , for this i have written a following code:
string fichier = #"C:\\Users\\Me\\Documents\\marie.docx";
FileInfo f = new FileInfo(fichier);
byte[] buffer = new byte[(int)f.Length];
System.IO.StreamReader strem = new System.IO.StreamReader(fichier);
String line = strem.ReadToEnd();
strem.Close();
IBufferedCipher cipher = CipherUtilities.GetCipher("RSA/ECB/PKCS1Padding");
string str = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA7cXmz0lTtzEuFAP0rR1f//RZZ8dGxa26I/LwJiNFqJULDvLjmiEHs+u+2gjc3Qm1cwcusuP+akCJIsGyn+9joEbEUKCaJOXbXsuqFKWFlsnfoCGTT8M1a5J2SNixsrLCim9P+qoGfml7JONUhWoiUVYqagRG4WgFmQHonttdnWEqk5yHtXp4ZzL+Bw54IaliyEzigBMW4k0rwMceR31MGnGGcplOynX6Ga5J3HZvLm2XoUQ6PAWw19yjmjiurwBugDOA2NdLOOR96Jxv39Kv/MyGXjjN3Z2hEsSVhHQ4j9RlEg0zsMhXoHJ/MsoVr5WKhEpCuuwp8IuQmwAFW1GoEwIDAQAB";
char[] cArray = str.ToCharArray();
byte[] pub_Array = new byte[cArray.Length];
for (int j = 0; j < cArray.Length; j++)
pub_Array[j] = (byte)cArray[j];
KeyParameter par = new KeyParameter(pub_Array);
cipher.Init(false, par);
//byte[] output = cipher.DoFinal(data);
int blockSize = cipher.GetBlockSize();
int outputSize = cipher.GetOutputSize(buffer.Length);
int leavedSize = buffer.Length % blockSize;
int blocksSize = leavedSize != 0 ? buffer.Length / blockSize + 1 : buffer.Length / blockSize;
byte[] raw = new byte[outputSize * blocksSize];
int i = 0;
while (buffer.Length - i * blockSize > 0)
{
if (buffer.Length - i * blockSize > blockSize)
cipher.DoFinal(buffer, i * blockSize, blockSize,
raw, i * outputSize);
else
cipher.DoFinal(buffer, i * blockSize,
buffer.Length - i * blockSize,
raw, i * outputSize);
i++;
}
// Ecriture du fichier chiffré sur le disque dur
StreamWriter envfos = null;
using (envfos = new StreamWriter("fichier_chiffrer.txt"))
{
envfos.Write(raw);
}
envfos.Close();
i have an
exception in : cipher.Init(false,par); << Impossible d'effectuer un cast d'un objet de type 'Org.BouncyCastle.Crypto.Parameters.KeyParameter' en type 'Org.BouncyCastle.Crypto.AsymmetricKeyParameter'.
Help please
any documentation in c# please;
think's in advance
Cordialement marie;
RSA encryption needs an AsymmeticKeyParameter as key. You can see the exception complain about that. You could use the RsaKeyParameter for this, but this will require you to supply 2 properties: Modulus and Exponent wich are both in the key.
Since you are using an already made X509 certificate you could also try to get the key from that file. I supplied some possible example code, but i don't know if it will work as i never even attemted to do something with X509 certificate. The code would replace your KeyParameter par = new KeyParameter(pub_Array); line.
X509CertificateParser parser = new X509CertificateParser();
AsymmeticKeyParameter par = parser.ReadCertificate(pub_array).GetPublicKey();
Here is a little snippet showing what is probably the easiest way to read the public key.
string str = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA7cXmz0lTtzEuFAP0rR1f//RZZ8dGxa26I/LwJiNFqJULDvLjmiEHs+u+2gjc3Qm1cwcusuP+akCJIsGyn+9joEbEUKCaJOXbXsuqFKWFlsnfoCGTT8M1a5J2SNixsrLCim9P+qoGfml7JONUhWoiUVYqagRG4WgFmQHonttdnWEqk5yHtXp4ZzL+Bw54IaliyEzigBMW4k0rwMceR31MGnGGcplOynX6Ga5J3HZvLm2XoUQ6PAWw19yjmjiurwBugDOA2NdLOOR96Jxv39Kv/MyGXjjN3Z2hEsSVhHQ4j9RlEg0zsMhXoHJ/MsoVr5WKhEpCuuwp8IuQmwAFW1GoEwIDAQAB";
string header = "-----BEGIN PUBLIC KEY\n";
string trailer = "\n-----END PUBLIC KEY";
str = header + str + trailer;
StringReader sr = new StringReader(str);
PemReader PemRdr = new PemReader(sr);
RsaKeyParameters KeyParams = (RsaKeyParameters)PemRdr.ReadObject();

Categories