Throws exception: Org.BouncyCastle.Crypto.InvalidCipherTextException: "mac check in GCM failed"
I am taring to decode metamask vault an sure that everithing with it must be OK
I can't find what's wrong
using System.Security.Cryptography;
using Org.BouncyCastle.Crypto.Parameters;
using System.Text;
using Jose;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto.Modes;
namespace net6metachecker
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void startbtn_Click(object sender, EventArgs e)
{
Decrypt1();
}
public void Decrypt1()
{
byte[] salt = Convert.FromBase64String("RXoBv+8Yu/nQhmj+nXMp8Rf57VLT8aYu5rvP5LEcq7Y=");
byte[] data = Convert.FromBase64String("cVZeRBJI7yzsN6lM9LS6tNSVYTU7IFy+UMAVsZjHa+/nGvXirE99pILb4+VdYANkEg05kbeoYgLwacqUNfZc+9llePvcLkVmzFtye4pYbVSkHtaGCKfFMb0gQxJb2xJz7Br4MHNzGEY7aZAkrWpx1KhIghA3uZBE5sjZ+vjw/aFg3w51xGBMgzwLdMcr8+Fru5Kyb5p1dVXSsMt7AFIQFg1BsOcbEiDNf/jkigxuJpILVYUY3qrUJmYh500frohZnxoh8fSPSWcyLbl08TKGE4DQuBeJ7cMcmmHnpvJ166BK1roOni4CMRIn84BBUr5DEW36+22i52vfPCvzgNUierIBoh3wUTZI/trHozXSLYg8t86XwLIzwNq4H08Ctss/Daivta/7mgE5KC7gesRoda6OLJ5XldxeibdtOprq1v+teeNVaZRRYTKs+cCUkrwxZVrjqzmnVMBxDegR3/gjchZRszm4hOWDfVR8JRhjpCKQmrLkOno=");
byte[] iv = Convert.FromBase64String("beg6WtZTF82na0IKb5Juhw==");
byte[] password = Encoding.UTF8.GetBytes("11111111");
byte[] key = PBKDF2.DeriveKey(password, salt, 10000, 256, HMAC.Create("HMACSHA256"));
GcmBlockCipher gcmBlockCipher = new GcmBlockCipher(new AesFastEngine());
AeadParameters parameters = new AeadParameters(new KeyParameter(key), 128, iv, null);
gcmBlockCipher.Init(false, parameters);
byte[] plainBytes = new byte[gcmBlockCipher.GetOutputSize(data.Length)];
int retLen = gcmBlockCipher.ProcessBytes(data, 0, data.Length, plainBytes, 0);
byte[] cc = gcmBlockCipher.GetMac();
int xx = gcmBlockCipher.DoFinal(plainBytes, retLen); // Exception is here
string x = Encoding.UTF8.GetString(plainBytes).TrimEnd("\r\n\0".ToCharArray());
MessageBox.Show(x);
}
}
}
Related
I'm porting the Following C# Encryption logic to php, i tried using OPENSSL to port the encryption but its giving me a weird error, i have no idea what im doing wrong maybe OPENSSL fault, padding? not sure
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Security.Cryptography;
using System.IO;
namespace Rextester
{
public class Program
{
public static ICryptoTransform DES;
public static DESCryptoServiceProvider Crypto = new DESCryptoServiceProvider();
public static MemoryStream memStream = new MemoryStream();
public static string encyrptedMessage;
public static void Main(string[] args)
{
Crypto.BlockSize = 64;
Crypto.FeedbackSize = 8;
Crypto.Mode = CipherMode.ECB;
Crypto.Padding = PaddingMode.PKCS7;
//Your code goes here
DES = Crypto.CreateEncryptor(Encoding.ASCII.GetBytes("L)#!&8#*"), Encoding.UTF8.GetBytes("CodeFast"));
CryptoStreamMode mode = CryptoStreamMode.Write;
// Set up streams and encrypt
byte[] messageBytes = Encoding.ASCII.GetBytes("yes");
CryptoStream cryptoStream = new CryptoStream(memStream, DES, mode);
cryptoStream.Write(messageBytes, 0, messageBytes.Length);
cryptoStream.FlushFinalBlock();
// Read the encrypted message from the memory stream
byte[] encryptedMessageBytes = new byte[memStream.Length];
memStream.Position = 0;
memStream.Read(encryptedMessageBytes, 0, encryptedMessageBytes.Length);
// Encode the encrypted message as base64 string
string encryptedMessage = Convert.ToBase64String(encryptedMessageBytes);
Console.WriteLine(encryptedMessage);
}
}
}
<?php
namespace encryption;
class DESCrypto{
private $key;
private $iv;
public function __construct(string $key, ?string $iv){
$this->key = $key;
$this->iv = utf8_encode($iv);
}
public function encrypt(string $text): string {
return openssl_encrypt($text,"DES-ECB",$this->key,OPENSSL_RAW_DATA,$this->iv);
}
public function decrypt(string $text): string {
return openssl_decrypt($text,"DES-ECB",$this->key,OPENSSL_RAW_DATA,$this->iv);
}
}
the C# Code is working fine meanwhile the php one returning the following error
Warning: openssl_decrypt(): IV passed is 4 bytes long which is longer than the 0 expected by selected cipher
Warning: openssl_encrypt(): IV passed is 4 bytes long which is longer than the 0 expected by selected cipher
I'm trying to set up a messing server for me and my friends and I ran into issues with RSA Decryption.
The correct keys are used
If I enable OAEP padding I get a error that simply states "OAEPpadding"
I'm losing my mind on this bug, I'm posting the script below.
Encryption works fine, its just decryption that's problematic
Please Help
using System;
using System.Net.Sockets;
using System.Net;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using System.Security.Cryptography;
using System.Xml.Serialization;
namespace Server_WIN_
{
class Program
{
public static XmlSerializer xs = new XmlSerializer(typeof(RSAParameters));
public static TcpListener server = new TcpListener(IPAddress.Parse("192.168.1.93"), 78);
public static TcpClient client = null;
public static NetworkStream canwetalk = null;
public static RSACryptoServiceProvider csp = new RSACryptoServiceProvider(4096);
public static RSAParameters publickey;
public static RSAParameters privatekey;
static Program()
{
server.Start();
csp.PersistKeyInCsp = false;
publickey = csp.ExportParameters(false);
privatekey = csp.ExportParameters(true);
client = server.AcceptTcpClient();
canwetalk = client.GetStream();
}
public static void Main(string[] args)
{
string strHostName = "";
strHostName = Dns.GetHostName();
// Then using host name, get the IP address list..
IPHostEntry ipEntry = Dns.GetHostEntry(strHostName);
IPAddress[] addr = ipEntry.AddressList;
Random ran = new Random();
HashAlgorithm sha = SHA256.Create();
string msg = "";
byte[] buffer = new byte[4096];
msg = "test";
msg = Encrypt(msg);
msg = Decrypt(msg);
Console.WriteLine(msg);
}
public static string PublicKeyString()
{
byte[] bytes = new byte[4096];
var sw = new StringWriter();
var xs = new XmlSerializer(typeof(RSAParameters));
xs.Serialize(sw, publickey);
return sw.ToString();
}
public static string PrivateKeyString()
{
byte[] bytes = new byte[4096];
var sw = new StringWriter();
var xs = new XmlSerializer(typeof(RSAParameters));
xs.Serialize(sw, privatekey);
return sw.ToString();
}
public static string Encrypt(string msg)
{
csp.ImportParameters(publickey);
byte[] data = System.Text.Encoding.ASCII.GetBytes(msg);
byte[] cipher = csp.Encrypt(data, false);
return System.Text.Encoding.ASCII.GetString(cipher);
}
public static string Decrypt(string msg)
{
try
{
csp.ImportParameters(privatekey);
byte[] decrypted = csp.Decrypt(System.Text.Encoding.ASCII.GetBytes(msg), false);
return System.Text.Encoding.Unicode.GetString(decrypted);
}
catch(CryptographicException e)
{
string p = e.ToString();
Console.WriteLine(p);
}
return "";
}
public static void ExportPublicKey()
{
string msg = PublicKeyString();
byte[] buffer = new byte[4096];
byte[] msg1 = System.Text.Encoding.ASCII.GetBytes(msg);
canwetalk.Write(msg1, 0, msg1.Length);
}
public static void ToStream(string msg, bool Encryption)
{
if (Encryption)
{
msg = Encrypt(msg);
byte[] msgbytes = System.Text.Encoding.ASCII.GetBytes(msg);
canwetalk.Write(msgbytes, 0, msgbytes.Length);
}
else
{
byte[] msgbytes = System.Text.Encoding.ASCII.GetBytes(msg);
canwetalk.Write(msgbytes, 0, msgbytes.Length);
}
}
public static string ReadStream()
{
byte[] buffer = new byte[4096];
int i = canwetalk.Read(buffer,0,buffer.Length);
return System.Text.Encoding.ASCII.GetString(buffer,0,i);
}
}
You can find this stackoverflow question helpful, but it's quite out of date Error occurred while decoding OAEP padding
Don't use the same provider. Do this instead:
var publicKey = RSA.Create();
publicKey.ImportParameters(PUB_PARAMS);
var privateKey = RSA.Create();
privateKey.ImportParameters(PRIV_PARAMS);
pretty new to c# and currently having a problem decrypting long passwords with an error of
Specified key is not a valid size for this algorithm
I know this has something to do with the encrypted password bits length not being supported but unsure how to go about suggested ways to allow for these longer passwords.
Here's my encrypt and decrypt
"cipherKey": "0123456789abcdef", "cipherVector":
"somereallycooliv"
using System;
using System.Security.Cryptography;
using System.IO;
using System.Text;
namespace DataApi
{
public class Encryption
{
private readonly IConfigurationService _configService;
private const string _vector = "cipherVector";
private const string _key = "cipherKey";
public Encryption(IConfigurationService configService)
{
_configService = configService;
}
public string EncryptString(string text)
{
if(string.IsNullOrEmpty(text))
{
return "";
}
try
{
var key = Encoding.UTF8.GetBytes(_configService.Get(_key));
byte[] IV = Encoding.ASCII.GetBytes(_configService.Get(_vector));
using (var aesAlg = Aes.Create())
{
using (var encryptor = aesAlg.CreateEncryptor(key, IV))
{
using (var msEncrypt = new MemoryStream())
{
using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
using (var swEncrypt = new StreamWriter(csEncrypt))
{
swEncrypt.Write(text);
}
var decryptedContent = msEncrypt.ToArray();
var result = new byte[IV.Length + decryptedContent.Length];
Buffer.BlockCopy(IV, 0, result, 0, IV.Length);
Buffer.BlockCopy(decryptedContent, 0, result, IV.Length, decryptedContent.Length);
return Convert.ToBase64String(result);
}
}
}
}
catch(Exception e) {
Loggifer.Error("Unable to encrypt string: "+text , e );
throw e;
}
}
public string DecryptString(string cipherText)
{
if(string.IsNullOrEmpty(cipherText))
{
return "";
}
try
{
var fullCipher = Convert.FromBase64String(cipherText);
byte[] IV = Encoding.ASCII.GetBytes(_configService.Get(_vector));
var cipher = new byte[16];
Buffer.BlockCopy(fullCipher, 0, IV, 0, IV.Length);
Buffer.BlockCopy(fullCipher, IV.Length, cipher, 0, IV.Length);
var key = Encoding.UTF8.GetBytes(_configService.Get(_key));
using (var aesAlg = Aes.Create())
{
using (var decryptor = aesAlg.CreateDecryptor(key, IV))
{
string result;
using (var msDecrypt = new MemoryStream(cipher))
{
using (var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
{
using (var srDecrypt = new StreamReader(csDecrypt))
{
result = srDecrypt.ReadToEnd();
}
}
}
return result;
}
}
}
catch (Exception e)
{
Loggifer.Error("Unable to decrypt string: "+cipherText , e );
throw e;
}
}
}
}
Two changes are required in the function public string DecryptString(string cipherText)
var cipher = new byte[fullCipher.Length - IV.Length];
and
Buffer.BlockCopy(fullCipher, IV.Length, cipher, 0, fullCipher.Length - IV.Length);
While playing with some AES C# wrappers found on SO and msdn (most notable here and here and here) I wrote the following code and I made the mistake of writing the IV to the CryptoStream.
What I noticed is that the output byte array contains the same values when the IV is written to the CryptoStream. If I comment out the line cryptoStream.Write(aes.IV, 0, aes.IV.Length);, it's fine, the output will be different.
My question is why in this case the output is the same? I realize that writing the IV to the CryptoStream is not what I am supposed to do but I find it odd especially given that the IV is different every time the function executes.
TestEncryption.cs:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
namespace Test
{
public class TestEncryption
{
public static readonly int KeyBitSize = 256;
private static readonly int BlockBitSize = 128;
public static readonly byte[] _salt = new byte[] { 23, 13, 23, 213, 15, 193, 134, 147, 223, 151 };
const int Iterations = 10000;
public static string Encrypt(byte[] inputBytes, string password)
{
using (var aes = new AesManaged
{
KeySize = KeyBitSize,
BlockSize = BlockBitSize,
Mode = CipherMode.CBC,
Padding = PaddingMode.PKCS7,
})
{
var cryptKey = CreateKey(password);
aes.GenerateIV();
Console.WriteLine("IV={0}", string.Join(", ", aes.IV.Select(b => b.ToString())));
using (var encrypter = aes.CreateEncryptor(cryptKey, aes.IV))
using (var output = new MemoryStream())
{
using (var cryptoStream = new CryptoStream(output, encrypter, CryptoStreamMode.Write))
{
cryptoStream.Write(aes.IV, 0, aes.IV.Length);
cryptoStream.Write(inputBytes, 0, inputBytes.Length);
cryptoStream.FlushFinalBlock();
}
Console.WriteLine("Output={0}", string.Join(", ", output.ToArray().Select(b => b.ToString())));
return Convert.ToBase64String(output.ToArray());
}
}
}
public static string Encrypt(string input, string password)
{
return Encrypt(Encoding.UTF8.GetBytes(input), password);
}
public static byte[] CreateKey(string password)
{
using (var rfc2898DeriveBytes = new Rfc2898DeriveBytes(password, _salt, Iterations))
return rfc2898DeriveBytes.GetBytes(32);
}
}
}
Program.cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
namespace Test
{
class Program
{
static void Main(string[] args)
{
//Test1();
Test2();
Console.ReadLine();
}
private static void Test2()
{
string text = "some longer text";
string pwd = "test2";
String encrypt1 = TestEncryption.Encrypt(text, pwd);
String encrypt2 = TestEncryption.Encrypt(text, pwd);
Console.WriteLine(encrypt1 == encrypt2);
}
}
}
I've used RadPersistenceManager with asp.net and follow the following guide :
http://demos.telerik.com/aspnet-ajax/persistence-framework/examples/custom-storage-provider/defaultcs.aspx.
But when I implement this in my project the following exception appears:
Title: xxxx.aspx, xxxxx Method Name:
Unable to read storage content. Could not find file
'C:\inetpub\wwwroot\XXXX\App_Data\TelerikAspNetRadControlsPersistedState'.
Exception: at
Telerik.Web.UI.PersistenceFramework.AppDataStorageProvider.LoadStateFromStorage(String
key) at Telerik.Web.UI.RadPersistenceManager.LoadState() at GraphicalUserInterface.JobBasket.LoadGridJobBasket()
That's the default storage provider key. If the control is looking for it, then your custom provider is not in effect at all.
Make sure you have everything from the demo, primarily:
the lines that set the custom storage provider:
protected void Page_Init(object sender, EventArgs e)
{
RadPersistenceManager1.StorageProviderKey = CookieName;
RadPersistenceManager1.StorageProvider = new CookieStorageProvider(CookieName);
}
and the custom storage provider itself:
using System;
using System.Linq;
using System.Web;
using Telerik.Web.UI.PersistenceFramework;
using System.IO;
using System.IO.Compression;
using System.Text;
public class CookieStorageProvider : IStateStorageProvider
{
private static readonly Encoding AsciiEncoding = System.Text.Encoding.ASCII;
private static readonly int MaxCookieSize = 4000;
private static readonly int LengthDataByteCount = sizeof(Int32);
private string StorageKey { get; set; }
#region IStateStorageProvider
public CookieStorageProvider(string key)
{
StorageKey = key;
}
public void SaveStateToStorage(string key, string serializedState)
{
HttpCookie cookie = new HttpCookie(StorageKey);
string settingsData = CompressString(serializedState);
if (settingsData.Length > MaxCookieSize)
{
throw new ArgumentOutOfRangeException("Current settings exceed 4k in compressed form! Operation canceled!");
}
cookie.Value = settingsData;
HttpContext.Current.Response.Cookies.Add(cookie);
}
public string LoadStateFromStorage(string key)
{
return DecompressString(HttpContext.Current.Request.Cookies[StorageKey].Value.ToString());
}
#endregion
private string CompressString(string inputString)
{
byte[] outputBytes = null;
byte[] inputBytes = AsciiEncoding.GetBytes(inputString);
using (MemoryStream ms = new MemoryStream())
{
using (GZipStream zipStream = new GZipStream(ms, CompressionMode.Compress))
{
zipStream.Write(inputBytes, 0, inputBytes.Length);
}
outputBytes = ms.ToArray();
}
return Convert.ToBase64String(AddDataCount(outputBytes, inputBytes.Length));
}
private string DecompressString(string inputString)
{
string outputString = String.Empty;
byte[] inputBytes = Convert.FromBase64String(inputString);
Int32 lengthDataArray = BitConverter.ToInt32(inputBytes, inputBytes.Length - LengthDataByteCount);
byte[] outputBytes = new byte[lengthDataArray];
using (MemoryStream ms = new MemoryStream(RemoveDataCount(inputBytes)))
{
using (GZipStream zipStream = new GZipStream(ms, CompressionMode.Decompress))
{
zipStream.Read(outputBytes, 0, outputBytes.Length);
}
outputString = AsciiEncoding.GetString(outputBytes);
}
return outputString;
}
private byte[] AddDataCount(byte[] inputArray, Int32 length)
{
byte[] lengthDataArray = BitConverter.GetBytes(length);
Array.Resize<byte>(ref inputArray, inputArray.Length + LengthDataByteCount);
Array.Copy(lengthDataArray, 0, inputArray, inputArray.Length - LengthDataByteCount, LengthDataByteCount);
return inputArray;
}
private byte[] RemoveDataCount(byte[] inputArray)
{
Array.Resize<byte>(ref inputArray, inputArray.Length - LengthDataByteCount);
return inputArray;
}
}
The different between the demo and my example that I need to load the persistence configurations on page load instead of load button. so it seems some times the CookieStorageProvider not initiated in Page_Init, so I added it in page_load instead.