

Kas Ob.
Members-
Content Count
626 -
Joined
-
Last visited
-
Days Won
10
Everything posted by Kas Ob.
-
What is the algorithm used to derive the key to a TMyEncryptor ?
Kas Ob. replied to dormky's topic in Databases
Tomorrow will try to figure something for you, no promise though, after almost two hours digging into this, i can say the encryption is utterly broken and non standard CBC, it is wrong ! -
What is the algorithm used to derive the key to a TMyEncryptor ?
Kas Ob. replied to dormky's topic in Databases
I don't have any experience with LockBox3, and the fact there is memory leak(s) is enough reason to stay away form it, Anyway.. 41 is Ord('A'), in other word it looks it didn't encrypt anything, to confirm try 'B', if you got 42 then either the library is broken or you are using it wrong ! -
What is the algorithm used to derive the key to a TMyEncryptor ?
Kas Ob. replied to dormky's topic in Databases
Just to fix your problem and workarounds The hash of the password is generated from the WideString of encoded password so const PASSWORD = 'pass'; var keyBytes, PassBytes: TBytes; HashSHA1: THashAlgorithm; HashMD5: THashAlgorithm; begin PassBytes := BytesOf(@WideString(PASSWORD)[1], Length(PASSWORD) * SizeOf(WideChar)); HashSHA1 := THash_SHA1.Create; try HashSHA1.Initialize; HashSHA1.ComputeHash(PassBytes); HashMD5 := THash_MD5.Create; try HashMD5.Initialize; HashMD5.ComputeHash(PassBytes); keyBytes := HashSHA1.Hash + HashMD5.Hash; SetLength(keyBytes, 32); // doing it here is better, triming here 32 for BlowFish or we can later use specify length at 32 with SetKey finally HashMD5.Free; end; finally HashSHA1.Free; end; .... table2.Encryption.Encryptor.SetKey(keyBytes, 0, Length(keyBytes)); // length should be 32 but we don't want to overflow 1) Any hash library will do the same you are free to use your own 2) The length is critical so make sure you are feeding 32 bytes, (and no more ! as strangely enough it does affect the output, meaning the SetKey is not protected from overflowing) 3) There is two version of SetKey, one is bugged and wrong the other does work fine, use the one with the offset and require TBytes as parameter, the one with 3 parameters. -
What is the algorithm used to derive the key to a TMyEncryptor ?
Kas Ob. replied to dormky's topic in Databases
Also SetKey is buggy !!! and not only ! procedure TCREncryptor.SetKey(const Key; Count: Integer); begin SetKey(TBytes(@Key), 0, Count); // TBytes(@Key) instead of TBytes(Key) end; procedure TCREncryptor.SetKey(const Key: TBytes; Offset, Count: Integer); -
What is the algorithm used to derive the key to a TMyEncryptor ?
Kas Ob. replied to dormky's topic in Databases
Have a good weekend too ! and now i do understand your points, also it took me long time as i don't want to mess with packages installation, as MyDAC and UniDAC can't be installed together unless the DAC version is identical, anyway... 1) The i described building the key is working fine, i checked and it is fine. here a simple way to build the key and use it using only UniDAC classes var keyBytes: TBytes; HashSHA1 : THashAlgorithm; HashMD5 : THashAlgorithm; begin HashSHA1 := THash_SHA1.Create; try HashSHA1.Initialize; HashSHA1.ComputeHash(BytesOf('pass')); HashMD5 := THash_MD5.Create; try HashMD5.Initialize; HashMD5.ComputeHash(BytesOf('pass')); keyBytes := HashSHA1.Hash + HashMD5.Hash; finally HashMD5.Free; end; finally HashSHA1.Free; end; 2) The encoding and decoding using CBC without padding is fine as i described it, here your 'A' with ehTag and ehTagAndHash in order C544E5292C9C42A5B94FE279127029010796125FFF7BB9A7408E02812A51D5F81FC2053401075D2A C544E5292C9C42A5B94FE27912702901DF4BEED6024BC5FE214A4205B1EE9981DAF4C7C56DCD4CE23D88E2EE9568BA546C007C63D9131C1B while with none it is two bytes E2 Now what is going on, that is strange thing to encrypt without IV, in fact you can't and shouldn't not do that , that is wrong on so many levels !!!!! The IV is zeroed in this case, and this is what you are missing, simple like that. Anyway E2 is HEX you need to de-hex it first then perform decryption in CBC mode, may be i missed mentioning this, but hey.. i don't know if you don't know that encryption with DB should be either binary in blob or HEX in plain text fields. -------------- Additional information changing the code a little to insert two 'A' rows, to show the information leak with ehNone we have two rows have the same encrypted value two chars (value = 'E2'), leaking critical information, exposing the data is identical with ehTag we have C544E5292C9C42A5B94FE27912702901CA9469BBB8503499CDFA76E7E84DBE9BCB48BF853F5A2643 C544E5292C9C42A5B94FE279127029010F89F0C11CB311D592EA28B171C712B5C7725B0130002CE8 and with ehTagAndHash C544E5292C9C42A5B94FE2791270290152F2428A526B0345481FAB80E42E687379477B776DCD4CE23D88E2EE9568BA546C007C63D9131C1B C544E5292C9C42A5B94FE2791270290173F9E56EB70F416E1C5B5CAD820E2220584574896DCD4CE23D88E2EE9568BA546C007C63D9131C1B Now do you see the information leak ?!, yes the hash is the same with ehTagAndHash exposing that the encrypted data was the same !! So until DevArt fix this, everyone should only use "ehTag" -
What is the algorithm used to derive the key to a TMyEncryptor ?
Kas Ob. replied to dormky's topic in Databases
I am lost here, what metadata ? What "A" and where did you get it, are trying to encrypt ? Tried what ? there is no hardcoded IV. IV is randomly generated as i said and included in the bytes/blob/strings/widestrings/memo... encrypted data -
What is the algorithm used to derive the key to a TMyEncryptor ?
Kas Ob. replied to dormky's topic in Databases
Magic number is fixed 4 bytes value implemented in TCREncryptor as header its value "BAADF00D" in HEX, Sorry, for my writing way, well i am trying my best to explain, the problem i can't know where your knowledge limit about encryption to expand, so i write in a way i see serve the most. You have problem understanding symmetric encryption and its modes, you need to read more, and i will expand here what can help you. Yes all symmetric algorithms including BlowFish need specific block size, but it doesn't affect the output, the output is affected by the mode of the encryption, ...... i am not going to torture you with more text, Pad the god damn thing with anything to make it work ! is that better, but don't use any specific padding on decryption because it will fail ! , if your python library enforced to use padding then look for different library that allow no padding, and by padding i mean the algorithm defined in RFCs, not the block padding to ensure the block length, the encrypted data should be already multiple of 8. again the structure of the encrypted data, these concatenated KEY_GUID + IV +CIPHER [+HASH] KEY_GUID is fixed constant of 16 bytes declared internally declared and shipped unencrypted, it has no weight or value on encryption, starting with $C5 .. ending with $01, simply an identifier that the encryption done by DevArt library. IV well .. 8 bytes HASH depends on the Hash algorithm SHA1 or MD5 (property in the encryptor compenent) and if "ehTag" then it will not be included while "ehTagAndHash" means it is there CIPHER is INTERNAL_HEADER + PLAIN_DATA INTERNAL_HEADER is 8 bytes long, contains magic number, aka constant of 4 bytes with "$BAADF00D" in HEX , followed by 4 bytes contain the PLAIN_TEXT length To generate the key, calculate SHA1 and MD5 of the password then concat them, then use the first bytes to fit the key length you need ! simple as that IV you have it in above after KEY_GUID Don't use BlowFish implementation that require padding ! Hope that helps. -
What is the algorithm used to derive the key to a TMyEncryptor ?
Kas Ob. replied to dormky's topic in Databases
Padding has nothing to do with symmetric encryption itself, padding is standardized way to prevent data lose, many libraries force you to use padding out of best practice and to comply with Modern Security standards, in other words to prevent you from shooting your foot, but there is also libraries (if not all of them) that allow you to manually handle this. And you said you are using , in Delphi ? in Python ? DevArt library ? TCREncryptor doesn't use padding PKCS7 or any other, it does ship the length (4 bytes length) after magic number before the encrypted data and after the random IV. Now i do understand that, and i am trying to help by explaining, your lack of understanding padding and when to use it, will stop you, TCREncryptor doesn't use padding as you assume. No joy there, because no padding, if you insist then pad it with 0 or random, with CBC it will not make a difference, as you will already have the length as i explained, right before the data. Now to your problem, Are you trying to decode the data in full ? As i explained the encrypted data are structured and you only need to decrypt part of it, if you see the lines i pasted above The encrypted data start at KEY_GUID_LEN + IV_LEN , 16+8 bytes, at 24, the length is ... till the end in case of "ehTag" or leaving the length of the hash to the according algorithm when "ehTagAndHash", in my UniDAC version there is only two hash algorithms MD5 and SHA1. The encrypted data include INTERNAL_HEADER_LEN bytes which is 8 bytes, this is the magic number with the length (removing the need for padding), so after decryption you need to check for the magic number and get the length then trim the decrypted data accoring to the length. -
What is the algorithm used to derive the key to a TMyEncryptor ?
Kas Ob. replied to dormky's topic in Databases
So after looking more at the encryption code, i stand with claim above, but .. It could be my old and outdated sources, they either : 1) Should hashed the data along with the randomly generated IV, and leave it out of the encryption, or 2) They should have encrypted the hash along with the data, as this looks like a single mistake (old mistake), it might be changed or fixed, though this will break compatibility between versions, the code to fix this FEncryptor.EncodeBuffer(TValueArr(Result), KEY_GUID_LEN + IV_LEN, CipherLen - HashLen, TValueArr(Result), KEY_GUID_LEN + IV_LEN); // should be FEncryptor.EncodeBuffer(TValueArr(Result), KEY_GUID_LEN + IV_LEN, CipherLen , TValueArr(Result), KEY_GUID_LEN + IV_LEN); Any fix will break compatibility, so in my opinion they should deprecate "ehTagAndHash" and use it only for decryption, and introduce ehTagAndHash2 with either of two suggestions above, but this will break compatibility backward too. Of course any changes of the above suggestion need adjustment in the decryption too. -
What is the algorithm used to derive the key to a TMyEncryptor ?
Kas Ob. replied to dormky's topic in Databases
Yes, (though outdated). Also yes. Your problem is not with the key itself, the key literally as i mentioned above, concatenating SHA1 and MD5 of the password, also the mode is CBC, so less work there. Your problem is in the code in TCREncryptor.Decrypt (and TCREncryptor.EncryptBytes) , these are very nicely done and very secure with authenticated encryption (with TagAndHash enabled), along random IV for each and every encryption operation followed by magic number "$BAADF00D" indicates the length of the data, hence removing the need for padding, it is well done until they missed to include hashing the IV with data (!!) this will leak information about the encrypted data. You are more secure with only "ehTag" in DataHeader property than "ehTagAndHash", no leaked information about the data, preventing any differential analysis, but with this you will lose the authentication. I am sorry that i can't share any source code from a proprietary code licensed to me, as you seem you don't have it, but with the above few lines you can ask them to fix their mistake and answer your support ticket. Hope that helps. -
What is the algorithm used to derive the key to a TMyEncryptor ?
Kas Ob. replied to dormky's topic in Databases
However, also i looked at my UniDAC (also expired but way newer than MyDAC) and there is TUniEncryptor and as the DAC components are shared between all DevArt libraries, i think the algorithm is still that old and with not best practice or standard password-key derivation, as changing it will break compatibility unless it is explicitly had an option to switch to newer one, and i don't see such option, in the online help for the latest ones. -
What is the algorithm used to derive the key to a TMyEncryptor ?
Kas Ob. replied to dormky's topic in Databases
My MyDAC expired long time ago, and i never used their Password2Key algorithm, i always used a key directly with the encryption, but when needed to be password derived i used HMACSHA256, the algorithm to derive the key (in the my TCREncryptor) is outdated and not secure enough to provide 256bit security and may be not even enough for 128bit, the code does concatenate the SHA1 with MD5 of the password. Anyways, you would better contact their support for this question in case you can't recognize the used algorithm, while if you have the source as i do, then it should be in "procedure TCREncryptor.Password2Key;", but again in MyDAC there is no TMyEncryptor, there is only TCREncryptor, which means they did refactor this and may be the algorithm too. -
Try this procedure TForm10.Button1Click(Sender: TObject); var MyReg: TRegistry; begin MyReg := TRegistry.Create; try MyReg.RootKey := HKEY_CURRENT_USER; if MyReg.KeyExists('\Control Panel\Cursors') then begin MyReg.Access := KEY_WRITE or KEY_READ or KEY_WOW64_64KEY; // KEY_WRITE or KEY_READ together or we can separate them per operation if MyReg.OpenKey('\Control Panel\Cursors', False) then begin //st := MyReg.ReadString(''); MyReg.WriteString('', 'Windows Black'); end; end; finally MyReg.Free; end; end;
-
Help needed in testing emulated GetTickCount32/64
Kas Ob. replied to Kas Ob.'s topic in Algorithms, Data Structures and Class Design
I want to know and solve this, away from Windows Server 2003 and Windows XP rare existence, it is nice to have unified version to support them all, this single API stopped a punch of great and old software and split many repository. I don't see this as stupid or waste of time, if a time spent lead to a result in testing something, success or failure, for me this is well spent time. -
Help needed in testing emulated GetTickCount32/64
Kas Ob. replied to Kas Ob.'s topic in Algorithms, Data Structures and Class Design
Great and perfect and Thank you ! -
Help needed in testing emulated GetTickCount32/64
Kas Ob. replied to Kas Ob.'s topic in Algorithms, Data Structures and Class Design
Right, i should have mentioned that may be as i read that second source you linked. According to this i have the it should (might) work for all starting from Windows XP SP2/SP3 and Server 2003 SP1, and that include 32Bit and 64Bit , as shown per declaration with 64bit size in that link, It is the same declared in DDK headers https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ntddk/ns-ntddk-kuser_shared_data also here explain the size of KSYSTEM_TIME https://osm.hpi.de/wrk/2007/08/getting-os-information-the-kuser_shared_data-structure/ And there a confession to make there is a condition i omitted in the code because i don't see it as big relevant, in 64bit there is a loop to establish that High2Time and High3Time are identical, this happen if updating one was happening at this very exact moment, i tried to slow my CPU by overloading up to 100%, and couldn't make this trigger, then tried to downclock and overclock CPU, as mine is Intel unlocked (model with "k"), yet even over more than an hour and in both cases could capture such case not even once, and i am not saying it is right to capture it, but i am saying statistically i satisfied, also even when they are not identical, meaning the result will be as much as it was like 100ns before, so no harm there, this can affect and important for kernel drivers, but can not be critical for any software in user mode. -
Well, not exactly, QueryPerformanceCounter does have higher resolution but with lower accuracy, it is tied to the CPU cycles, at that low level, yes it has very high resolution, but when the CPU throttle or switch power profile it will start to return far from accurate result, also will be far from accurate in hibernate, GetTickCount on other hand depends or gets its clock timing using BIOS clock interrupt which in turn gets its time from the MotherBoard chipset, this one doesn't suffer from power profile effect, these chipset runs at constant frequency and they are very accurate but with lower precision than the CPU, due to their difference in base frequencies (CPU and motherboard chipset).
-
I opened a thread about GetTickCount, that safely replace this GetTickCount64, but will wait until confirmation of success result as explained there, before suggesting to replace any short coming of GetTickCount64 this with that direct (emulated) version.
-
On side note: I never saw "/ph" and "/nph" being used, and honestly don't know what exactly they do, only can imagine or assume, If you have any resources on this, i would appreciate sharing !
-
Nice ! Few thoughts : 1) Albeit there is no mention for Remove/Delete a signature in Microsoft documentation in three different places for SignTool https://learn.microsoft.com/en-us/windows-hardware/drivers/devtest/signtool https://learn.microsoft.com/en-us/dotnet/framework/tools/signtool-exe https://learn.microsoft.com/en-us/windows/win32/seccrypto/signtool The command "remove" is useful and pretty needed, sometimes it is essential, example, you want to switch form internal debugging/testing signature to release, and don't want to ship with your organization internally issued signatures and its certificate, so remove/delete is needed, and it is there within SignTool.exe, i remember have seen in the documentation in the past ! 2) With SignTool there is "/ac" option for the Sign command, this one can be crucial for new CA certificates, as best practice dictate to include the chain of trust path excluding the root, root must not be included as it will be considered waste and manipulation (root should be presented and trusted by different source like OS store or any higher/adequate administrative authority), but CAs between end point and root can be the line between verification and failure, including the chain of trust is essential for old systems and/or new CAs, so you might need to consider to add it. 3) Identifying or choose the certificate by thumbprint is OK, but i would suggest to use similar method like SignTool and IIS, by adding "IssuedTo/SubjectName", this will minimize the hustle of update thumbprint on client/terminal side when more than 1 certificate do exist, as they will exist, like generally you order new certificate while the soon to expired still there, if you look at IIS, it always select the newer certificate after filtering the available certificates with Subject Alternative Name match the domain name, same for sign tool does the same by "/n" option and looking for the SubjectName, so adding this also make sense. Well, this comes to mind and thank you again !
-
Yes not for everyone, yet the decentralization and distribution of the signature log might help or at least increase the chance of avoiding catastrophic failure or again at least faster response, in case of compromise did happen, some might look and see logs with different colors of the names and/or the time of multi signature happened at 3AM then you go why and what Andres had signed binaries, could his station being hijacked !, lets notify him or the responsible person. Anyway, food for thought, and this what i did and my clients loved it !
-
Then i would expand on this and suggest to make like what i did, on every sing issued the result on both GUI and console client side, it does grab last few signing operation and disclose them to every one is singing, as the best security is transparency and awareness, this means any singing developer can have a glance of what have being signed last 5-10 singing procedures, with time, dates, authorization and the binary name. Just food for thoughts. And thank you very much !
-
@Vincent Parrett Feature suggestion even before seeing this great tool As i already did 3 projects for 3 different clients, although it wasn't for USB or hardware tokens, but for usual certificate and its private key, the project was to keep the private key securely stored away from developers machines, yet monitor what executables were signed and by whom, stored IPs and devs authentication in detailed nice logs, also the administrator could allow only the digest to be shipped to the server but also allow the administrator to choose who can not sign without uploading the whole binary to be stored on the server for .. security and trust reasons. My suggestion is to expand or at least consider the forced operation logging on server side, this is not something belongs to best practice and i am sure it will be requested sooner or later.
-
Name suggestion if you interested : "DSign" or "DSigning" from Distributed .. ihm... i meant Delphi . The latter yield zero search result on both DDG and Google.
-
Only 2 GB available despite IMAGE_FILE_LARGE_ADDRESS_AWARE
Kas Ob. replied to dummzeuch's topic in Windows API
Yes they have reasons, and this 100% doesn't include solving your mentioned problem, these APIs are about locking/reserving physical memory, to one end and one reason, minimizing page faults for one critical application, hence recover or reserve performance as much as possible, and by performance i mean the just to prevent losing performance due to high memory usage and paging to file, and that is it. I can't imagine how this can help your application not crashing, but i can few scenarios where it delay the crash enough that you don't notice, this does not fix the problem, and there is bug(s) somewhere, it might be 1) Your bug very similar to the @dummzeuch mentioned, it is coming from casting pointer to signed integer then perform some operations on that integer, like shuffling it to other variables, or do some arithmetic operation with it, back in days 32bit application had 2GB and there wasn't a problem, i mean there wasn't crashing or access violations (because the problem is there waiting), then comes the boot switch /3GB that allowed/added one extra GB to the memory rendering all the abusing of the pointer as access violation, but this didn't happen or noticed right away as it will happen arbitrary, and only when your application utilized so much memory, in newer Windows version, the OS started to make this allocation addresses more arbitrary, hence these bugs started to show even if your application didn't utilize a lot of memory, anyways, these access violation and miss use of pointers, could be easily found and fixed by use the FastMM4 with MEM_TOP_DOWN, which i remember is default, hence will fixed right away, without you might depend on luck and high memory usage to capture. 2) Your application in fact using high volume of memory but it does abuse threading and miss using timing, if you have one Sleep because you are assuming an operation will take 5ms and you gave it something like 500ms, that should be fine, right ? NO ! , you are wrongly assuming this can be enough, because when when paging hit, the operation will block, by operation i mean a single CPU instruction will trigger OS VMM intervention due to hard page fault, and this thread will block until VMM free some physical memory, not really free (!!) but stop another thread/process and then write its memory from the physical to the page file, then load you paged memory, then continue your thread, by continue i mean literally re-execute that single instruction, the one stopped the earth planet form rotation. These bugs coming from miss using timing where very frequent back in days with HDD, with SSD it is faster and wrong logic might pass unchallenged, yet with heavy software running on OS like Windows Defender that literally capable to utilize the disk operation at tens of thousands operations per second when it does scan, these bugs come to light again. So i hope that was readable and clear, and of course i hope helps identifying your bugs, but one thing is for sure denying physical memory by manipulating working set, is not good sign at all, let your application be free of bugs and let it take small extra time due paging, and let the OS perform as intended.