We´re struggeling with the decryption of DESFire Data. We´ve authenticated successfully and could decrypt RndA´ which was the same as the RndA we´ve created.
Now we try to read an encyphered File from position 0 for 16 bytes.
From some java library we could figure out, that we have to use the encyphered Command as IV for the decryption. Is that right?
Here the examples:
SessionKey: 0ba1caf83a26a72170149b7504895f34
ReadCommand: bd00000000100000
Crc32C for Cmd: D9CEE76B
Secret: 6a0d0f0d5c8f054b1e5914a42e49728622774c6272e5c34a69ed302251576aaf
So now we concat the ReadCommand with Crc32C:
bd00000000100000D9CEE76B
Then we padd Zeros up to 16 Bytes
bd00000000100000D9CEE76B00000000
Then we generate e(cmd + crc + padding) with session key and IV 0 to gain the next iv for decrypting the resposne:
77E24803B5401C61F657607923E5A318
Now we decrypt the secret with session Key and IV:=e(cmd + crc32) and are getting:
D1E9A4726C2A5C3FD5938E714C07524EF1F74BD9000000000000000000000000
There are many Zeros which let me think we are not far away from the answer.
So please someone tell us, what is wrong?
We are using this library for Crc32C
And here the full code we are using within a test:
[Theory]
[InlineData("6a0d0f0d5c8f054b1e5914a42e49728622774c6272e5c34a69ed302251576aaf", "0ba1caf83a26a72170149b7504895f34", "bd00000000100000")]
public void DecryptData_Test(string secretS, string sessionKeyS, string cmdS)
{
var cryptoAlgoFactory = new Func<SymmetricAlgorithm>(() => Aes.Create());
var keyLength = 16;
var secret = EncriptionHelper.StringToByte(secretS);
var sessionKey = EncriptionHelper.StringToByte(sessionKeyS);
var cmd = EncriptionHelper.StringToByte(cmdS);
var crytoAlgo = cryptoAlgoFactory();
crytoAlgo.Mode = CipherMode.CBC;
crytoAlgo.Padding = PaddingMode.None;
var encryptor = crytoAlgo.CreateEncryptor(sessionKey, new byte[keyLength]);
var crc32 = BitConverter.GetBytes(Crc32C.Crc32CAlgorithm.Compute(cmd));
var padding = 0;
if ((cmd.Length + crc32.Length) % keyLength != 0)
padding = keyLength - ((cmd.Length + crc32.Length) % keyLength);
var result = new byte[cmd.Length + crc32.Length + padding];
Array.Copy(cmd, result, cmd.Length);
Array.Copy(crc32, 0, result, cmd.Length, crc32.Length);
var iv = encryptor.TransformFinalBlock(result, 0, result.Length);
crytoAlgo = cryptoAlgoFactory();
crytoAlgo.Mode = CipherMode.CBC;
crytoAlgo.Padding = PaddingMode.None;
var decryptor = crytoAlgo.CreateDecryptor(sessionKey, iv);
var plain = decryptor.TransformFinalBlock(secret, 0, secret.Length);
Assert.NotNull(plain);
}
We´ve found out, that we have to encrypt the command with CMACing and without CRC32C.
Therefore the following solution:
SessionKey: 0ba1caf83a26a72170149b7504895f34
ReadCommand: bd00000000100000
Secret: 6a0d0f0d5c8f054b1e5914a42e49728622774c6272e5c34a69ed302251576aaf
First Encrypt the cmd with CMACing to get the following IV for further decrypting (Note to use the SessionKey):
A70BEC41E95A706F11F7DA3D59F2F256
Then decrypt the secret in CBC Mode with IV cmac(cmd) to get the result:
01000030303030313233343536100300F1F74BD9000000000000000000000000
Within the CMACing there is still something wrong so we used an NuGet Packege which worked fine.
I've written some codes to send fax using faxcomlib. it work fine when running code in my windows application but i want to use my sending fax code in a windows service,the problem is go here when i try to send fax by using windows service, my problem is that when i sending text files,or pdf or word document it work fine,but when sending any image format like .jpg,.tiff,... i face to operation failed error and my service get hanged,i try this ways but unfortunately i didn't get any right anwser :
1- i get all permissions to my service and related folders
2- i try to convert images to the same format and size that fax printer use it ( CCITT T6 - 1740*2400)
3- i try to convert my images to pdf files and then send it but i cann't, despite already i did send pdf files without any errors.
and here is my codes for sendig fax :
if (ImageExtensions.Contains(System.IO.Path.GetExtension(tempFileName).ToUpperInvariant().Trim()))
{
string newFileName = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) + #"\Temp\" + System.IO.Path.GetFileNameWithoutExtension(currentAttachment) + ".tif";
Toranj.Base.Graphic.Imaging.SaveTiff(tempFileName, newFileName);
Bitmap tempImage = new Bitmap(tempFileName);
System.Drawing.Image newImage = Toranj.Base.Graphic.Imaging.Resize(tempImage, 1728, 2200, RotateFlipType.RotateNoneFlipXY, 204, 196);
tempImage.Dispose();
System.IO.File.Delete(tempFileName);
newImage.Save(tempFileName);
newImage.Dispose();
Toranj.Base.Graphic.Imaging.SaveTiff(tempFileName, newFileName);
//PdfDocument doc = new PdfDocument();
//doc.Pages.Add(new PdfPage());
//XGraphics xgr = XGraphics.FromPdfPage(doc.Pages[0]);
//XImage img = XImage.FromFile(tempFileName);
//xgr.DrawImage(img, 0, 0);
//doc.Save(newFileName);
//doc.Close();
fileList.Add(newFileName);
System.IO.File.Delete(tempFileName);
}
else
fileList.Add(tempFileName);
}
FAXCOMEXLib.FaxDocument currentDocument = new FAXCOMEXLib.FaxDocument();
string[] attachList = fileList.ToArray();
currentDocument.Bodies = attachList;
ShamsiDate curretnDate = new ShamsiDate(DateTime.Now);
currentDocument.DocumentName = "fax:" + curretnDate.PerSimpleDate();
currentDocument.Priority = FAXCOMEXLib.FAX_PRIORITY_TYPE_ENUM.fptHIGH;
currentDocument.Recipients.Add(currentRow["faxNumber"].ToString(), currentRow["RecipientName"].ToString());
currentDocument.AttachFaxToReceipt = true;
currentDocument.Sender.Title = "xxxxx";
currentDocument.Sender.Name = "";
currentDocument.Sender.City = "xxxxx";
currentDocument.Sender.Company = "xxxxx";
currentDocument.Sender.Country = "xxxxx";
currentDocument.Sender.Email = "xxxxx";
currentDocument.Sender.FaxNumber = "";
currentDocument.Sender.HomePhone = "";
currentDocument.Sender.TSID = "";
currentDocument.Sender.SaveDefaultSender();
object jobsId = new object();
currentDocument.ConnectedSubmit2(sendServer, out jobsId);
string[] jobID = (string[])jobsId;
can anyone help me?
in above code, if my files was image format files, i'll first change size,and save them az tiff format and convert it to the pdf format file to sending by fax but there is no change!!!
I am currently working on a C# forms application that needs to access a specific cookie on my computer, which I can do perfectly fine. Here's the issue:
Google stores cookies in SQLite, and I've downloaded Sqlite database browser to help me look at these values. What surprises me is that about half of the cookie values shows as empty (including the one I need), even though they are obviously not.
The db file is located at:
C:\Users\%username%\AppData\Local\Google\Chrome\User Data\Default\Cookies
On Chrome I have an addon called "Edit This Cookie" which allows me to directly modify cookies on the website I'm on. This addon can read these cookies, and the web browser can parse values through HTTP when needed for different requests, so they are definitely there - still, the SQLite browser, and my custom code both come to the conclusion that the particular value field is empty.
Why is that?
What is it that somehow prevents the field from being read by certain applications?
I've run into this same problem, and the code below provides a working example for anyone who is interested. All credit to Scherling, as the DPAPI was spot on.
public class ChromeCookieReader
{
public IEnumerable<Tuple<string,string>> ReadCookies(string hostName)
{
if (hostName == null) throw new ArgumentNullException("hostName");
var dbPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + #"\Google\Chrome\User Data\Default\Cookies";
if (!System.IO.File.Exists(dbPath)) throw new System.IO.FileNotFoundException("Cant find cookie store",dbPath); // race condition, but i'll risk it
var connectionString = "Data Source=" + dbPath + ";pooling=false";
using (var conn = new System.Data.SQLite.SQLiteConnection(connectionString))
using (var cmd = conn.CreateCommand())
{
var prm = cmd.CreateParameter();
prm.ParameterName = "hostName";
prm.Value = hostName;
cmd.Parameters.Add(prm);
cmd.CommandText = "SELECT name,encrypted_value FROM cookies WHERE host_key = #hostName";
conn.Open();
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
var encryptedData = (byte[]) reader[1];
var decodedData = System.Security.Cryptography.ProtectedData.Unprotect(encryptedData, null, System.Security.Cryptography.DataProtectionScope.CurrentUser);
var plainText = Encoding.ASCII.GetString(decodedData); // Looks like ASCII
yield return Tuple.Create(reader.GetString(0), plainText);
}
}
conn.Close();
}
}
}
Alright, so in case anyone is interested, I found a solution to this problem after alot of trial, error and googling.
Google Chrome cookies DB has 2 columns for storing values: "value" and "encrypted_value", the latter being used when the cookie stored was requested to be encrypted - often the case with certain confidential information and long-time session keys.
After figuring this out, I then needed to find a way to access this key, stored as a Blob value. I found several guides on how to do this, but the one that ended up paying of was: http://www.codeproject.com/Questions/56109/Reading-BLOB-in-Sqlite-using-C-NET-CF-PPC
Simply reading the value is not enough, as it is encrypted. - Google Chrome uses triple DES encryption with the current users password as seed on windows machines. In order to decrypt this in C#, one should use Windows Data Protection API (DPAPI), there are a few guides out there on how to make use of it.
Like Jasper's answer, in a PowerShell script (of course, customize the SQL query to your needs, and the path to your cookies location):
$cookieLocation = 'C:\Users\John\AppData\Local\Google\Chrome\User Data\Default\cookies'
$tempFileName = [System.IO.Path]::GetTempFileName()
"select writefile('$tempFileName', encrypted_value) from cookies where host_key = 'localhost' and path = '/api' and name = 'sessionId';" | sqlite3.exe "$cookieLocation"
$cookieAsEncryptedBytes = Get-Content -Encoding Byte "$tempFileName"
Remove-Item "$tempFileName"
Add-Type -AssemblyName System.Security
$cookieAsBytes = [System.Security.Cryptography.ProtectedData]::Unprotect($cookieAsEncryptedBytes, $null, [System.Security.Cryptography.DataProtectionScope]::CurrentUser)
$cookie = [System.Text.Encoding]::ASCII.GetString($cookieAsBytes)
$cookie
So I wanted to do this without writing to a tempfile every time but also without implementing a separate class as per jasper's solution. Like jasper, I found it easier and quicker to access the System.Data.SQLite.dll available here. It's not as elegant as a separate class, but it's what worked best for me:
Add-Type -AssemblyName System.Security
Add-Type -Path 'C:\Program Files\System.Data.SQLite\2015\bin\x64\System.Data.SQLite.dll'
Function Get-Last-Cookie {
Param(
[Parameter(Mandatory=$True)] $valueName,
[Parameter(Mandatory=$True)] $hostKey,
[Parameter(Mandatory=$True)] $dbDataSource
)
$conn = New-Object -TypeName System.Data.SQLite.SQLiteConnection
$conn.ConnectionString = "Data Source=$dbDataSource"
$conn.Open()
$command = $conn.CreateCommand()
$query = "SELECT encrypted_value FROM cookies WHERE name='$valueName' `
AND host_key='$hostKey' ORDER BY creation_utc DESC LIMIT 1"
$command.CommandText = $query
$adapter = New-Object -TypeName System.Data.SQLite.SQLiteDataAdapter $command
$dataset = New-Object System.Data.DataSet
[void]$adapter.Fill($dataset)
$command.Dispose();
$conn.Close();
$cookieAsEncryptedBytes = $dataset.Tables[0].Rows[0].ItemArray[0]
$cookieAsBytes = [System.Security.Cryptography.ProtectedData]::Unprotect($cookieAsEncryptedBytes, $null, [System.Security.Cryptography.DataProtectionScope]::CurrentUser)
return [System.Text.Encoding]::ASCII.GetString($cookieAsBytes)
}
$localAppDataPath = [Environment]::GetFolderPath([Environment+SpecialFolder]::LocalApplicationData)
$cookieDbPath = 'Google\Chrome\User Data\Default\Cookies'
$dbDataSource = Join-Path -Path $localAppDataPath -ChildPath $cookieDbPath
$plainCookie = Get-Last-Cookie 'acct' '.stackoverflow.com' $dbDataSource
Write-Host $plainCookie
I also found the Add-SqliteAssembly function by halr9000 to be very helpful when it came time to schedule my script in the windows task scheduler and realized that the task scheduler runs the x86 version of PowerShell and thus SQLite rather than the x64 I was using in the console.
The thing is that Google Chrome encrypts the data you need to read, so you have to decrypt it.
First, get a copy of the cookies file. Then read it using SQLite3. After that, get the encrypted bytes. And last, use the code below to decrypt it.
You'll need these Nugets:
using System.IO;
using System.Net;
using System.Data.SQLite;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto.Modes;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Crypto;
using Newtonsoft.Json.Linq;
The code so far:
File.Copy(Environment.GetEnvironmentVariable("APPDATA") + #"/../Local/Google/Chrome/User Data/Default/Cookies", #"./Cookies",true);
SQLiteConnection Cnn = new SQLiteConnection("Data Source=" + #"./Cookies" + ";pooling=false");
Cnn.Open();
SQLiteCommand cmd = new SQLiteCommand("SELECT host_key, name, value, encrypted_value FROM cookies WHERE name='mvrusername' OR name='mvrcookie' OR name='mikuki4'", Cnn);
SQLiteDataReader rdr = cmd.ExecuteReader();
while (rdr.Read())
{
byte[] encryptedData = (byte[])rdr["encrypted_value"];
string encKey = File.ReadAllText(Environment.GetEnvironmentVariable("APPDATA") + #"/../Local/Google/Chrome/User Data/Local State");
encKey = JObject.Parse(encKey)["os_crypt"]["encrypted_key"].ToString();
var decodedKey = System.Security.Cryptography.ProtectedData.Unprotect(Convert.FromBase64String(encKey).Skip(5).ToArray(), null, System.Security.Cryptography.DataProtectionScope.LocalMachine);
const int MAC_BIT_SIZE = 128;
const int NONCE_BIT_SIZE = 96;
using (var cipherStream = new MemoryStream(encryptedData))
using (var cipherReader = new BinaryReader(cipherStream))
{
var nonSecretPayload = cipherReader.ReadBytes(3);
var nonce = cipherReader.ReadBytes(NONCE_BIT_SIZE / 8);
var cipher = new GcmBlockCipher(new AesEngine());
var parameters = new AeadParameters(new KeyParameter(decodedKey), MAC_BIT_SIZE, nonce);
cipher.Init(false, parameters);
var cipherText = cipherReader.ReadBytes(encryptedData.Length);
var plainText = new byte[cipher.GetOutputSize(cipherText.Length)];
try
{
var len = cipher.ProcessBytes(cipherText, 0, cipherText.Length, plainText, 0);
cipher.DoFinal(plainText, len);
}
catch (InvalidCipherTextException)
{
}
string _cookie= Encoding.Default.GetString(plainText);
}
}
// Big thanks to https://stackoverflow.com/a/60611673/6481581 for answering how Chrome 80 and up changed the way cookies are encrypted.
# this powershell scripts exports your cookies to a format curl and wget understand
# Obs ! Each profile has its own cookes file , replace me (ysg ;o) with your win usr name
# aka wget -x --load-cookies cookies.txt http://stackoverflow.com/questions/22532870/encrypted-cookies-in-chrome
$cookieLocation = 'C:\Users\ysg\AppData\Local\Google\Chrome\User Data\Profile 1\Cookies'
$curl_cookies_file="C:\var\ygeo.reports.app.futurice.com.cookies.doc-pub-host.txt"
$tempFileName1 = [System.IO.Path]::GetTempFileName()
$tempFileName2 = [System.IO.Path]::GetTempFileName()
# adjust your filter in the where clause ...
"select writefile('$tempFileName1', encrypted_value) from cookies where host_key = '.futurice.com' ;" | sqlite3.exe "$cookieLocation"
$cookieAsEncryptedBytes = Get-Content -Encoding Byte "$tempFileName1"
Remove-Item "$tempFileName1"
Add-Type -AssemblyName System.Security
$cookieAsBytes = [System.Security.Cryptography.ProtectedData]::Unprotect($cookieAsEncryptedBytes, $null, [System.Security.Cryptography.DataProtectionScope]::CurrentUser)
$cookie = [System.Text.Encoding]::ASCII.GetString($cookieAsBytes)
$unquoted_cookie=$cookie -replace '"', ""
# adjust your filter in the where clause ...
"
select
host_key
, CASE WHEN httponly=0 THEN 'FALSE' ELSE 'TRUE' END
, path
, CASE WHEN secure=0 THEN 'FALSE' ELSE 'TRUE' END
, expires_utc
, name
, '$unquoted_cookie'
from cookies where host_key = '.futurice.com' ;" | sqlite3.exe -separator " " "$cookieLocation" > $curl_cookies_file
Get-ChildItem *.txt | ForEach-Object { (Get-Content $_) | Out-File -Encoding ASCII $_ }
# check the meta data table
#"PRAGMA table_info([cookies]);" | sqlite3.exe "$cookieLocation"
# src: https://github.com/daftano/cookies.txt/blob/master/src/popup.js
#content += escapeForPre(cookie.domain);
#content += "\t";
#content += escapeForPre((!cookie.hostOnly).toString().toUpperCase());
#content += "\t";
#content += escapeForPre(cookie.path);
#content += "\t";
#content += escapeForPre(cookie.secure.toString().toUpperCase());
#content += "\t";
#content += escapeForPre(cookie.expirationDate ? Math.round(cookie.expirationDate) : "0");
#content += "\t";
#content += escapeForPre(cookie.name);
#content += "\t";
#content += escapeForPre(cookie.value);
#content += "\n";
#
#0|creation_utc|INTEGER|1||1
#1|host_key|TEXT|1||0
#2|name|TEXT|1||0
#3|value|TEXT|1||0
#4|path|TEXT|1||0
#5|expires_utc|INTEGER|1||0
#6|secure|INTEGER|1||0
#7|httponly|INTEGER|1||0
#8|last_access_utc|INTEGER|1||0
#9|has_expires|INTEGER|1|1|0
#10|persistent|INTEGER|1|1|0
#11|priority|INTEGER|1|1|0
#12|encrypted_value|BLOB|0|''|0
#13|firstpartyonly|INTEGER|1|0|0
Just set "value" to the cookie you want, "encrypted_value" to NULL and "priority" to 0
I am in the processing of implementing a CNG ECDH and then I am trying to use the BCRYPT_KDF_SP80056A_CONCAT KDF to derive a symmetric AES256 key (BCryptDeriveKey()). I am having a problem (i always get back 0xc000000d status returned.)
i have generated a shared secret successfully and I have created the buffer desc "BCryptBufferDesc" which has an array of "BCryptBuffer" with 1 AlgorithmID, 1 PartyU and 1 PartyV "other info". I think I have the structures all defined and populated properly. I am just picking some "values" for PartyU and PartyV bytes (i tried 1 byte and 16 bytes for each but i get the same result). NIST documentation gives no details about what the other info should be..
i have followed the Microsoft web site for creating these structures, using their strings, defines, etc. I tried with the standard L"HASH" kdf and it works and i get the same derived key on both "sides", but with the concatenation KDF i always get the same 0xC000000D status back..
Has anybody else been able to successfully use BCRYPT_KDF_SP80056A_CONCAT CNG KDF? If you did, do you have any hints?
This worked for me:
ULONG derivedKeySize = 32;
BCryptBufferDesc params;
params.ulVersion = BCRYPTBUFFER_VERSION;
params.cBuffers = 3;
params.pBuffers = new BCryptBuffer[params.cBuffers];
params.pBuffers[0].cbBuffer = 0;
params.pBuffers[0].BufferType = KDF_ALGORITHMID;
params.pBuffers[0].pvBuffer = new byte[0];
params.pBuffers[1].cbBuffer = 0;
params.pBuffers[1].BufferType = KDF_PARTYUINFO;
params.pBuffers[1].pvBuffer = new byte[0];
params.pBuffers[2].cbBuffer = 0;
params.pBuffers[2].BufferType = KDF_PARTYVINFO;
params.pBuffers[2].pvBuffer = new byte[0];
NTSTATUS rv = BCryptDeriveKey(secretHandle, L"SP800_56A_CONCAT", ¶ms, NULL, 0, &derivedKeySize, 0);
if (rv != 0){/*fail*/}
UCHAR derivedKey = new UCHAR[derivedKeySize];
rv = BCryptDeriveKey(secretHandle, L"SP800_56A_CONCAT", ¶ms, derivedKey, derivedKeySize, &derivedKeySize, 0);
if (rv != 0){/*fail*/}
I was using as3Crypto with no probs
http://www.zedia.net/2009/as3crypto-and-php-what-a-fun-ride/
but then I saw some special characters and I realised I could encounter ampersands.
Which is a pain because they will be inserted into a query string.
Is there a way to ensure the as3Crypto encryption does not produce ampersands?
public function encrypt(txt:String = ''):String
{
var data:ByteArray = Hex.toArray(Hex.fromString(txt));
var pad:IPad = new PKCS5;
var mode:ICipher = Crypto.getCipher(type, key, pad);
pad.setBlockSize(mode.getBlockSize());
mode.encrypt(data);
return ''+Base64.encodeByteArray(data);
}
Assuming a standard base64 implementation, Base64.encodeByteArray(data); will not produce ampersands.