HNHacker News
TopNewBestAskShowJobs

sdrapkin

457 karma · joined April 20, 2015

submissionscomments
sdrapkin··on .NET: Avoid Using Guid.CreateVersion7
Guid.CreateVersion7 in .NET 9+ claims RFC 9562 compliance but violates its big-endian requirement for binary storage. This causes the same database index fragmentation that v7 UUIDs were designed to prevent. Testing with 100K PostgreSQL inserts shows rampant fragmentation (35% larger indexes) versus properly-implemented sequential GUIDs.
sdrapkin··on Fcrand (Go language): drop-in replacement for crypto/rand, up to 10x faster
fcrand (fast crypto/rand) is a high-performance drop-in replacement for Go's crypto/rand.
sdrapkin··on Fast cryptographically safe GUID generator for Go
No, Guid/uuids are defined as 128-bit labels used to uniquely identify objects in computer systems. This 128-bit/16-byte definition predates any RFCs that one may or may not choose to implement. I'm obviously aware of RFC 9562, and nowhere in the Guid library do I claim implementation of it. RFC 9562 is a choice, and one that should not be made blindly, or for you. It all starts with 16 random bytes. Google's uuid starts that way, and virtually every other Guid/uuid implementation. Then, on top of that building block, one may tweak additional non-random bits if the usecase truly requires it. If it does - you can do it quickly and cheaply on top of 16 random bytes. If the usecase does not require it (99% of cases), you're better off with the foundational 16 random bytes. The perspective of "your 16 random bytes do not implement RFC 9562 - BAD, BAD!" is very myopic. But if wasting bits on versions and variants is something that helps someone sleep better - they can easily and cheaply achieve that with a couple of bit ops. RFC 9562 robs developers of that choice.
sdrapkin··on Fast cryptographically safe GUID generator for Go
Agreed. So at worst they (Golang developers) should be indifferent, and at best they should opt for the faster choice. With serverless code billing by the second, faster choices are directly correlated to lower costs.
sdrapkin··on Fast cryptographically safe GUID generator for Go
Amazon AWS S3 web servers process millions of requests per second, and each response generates a random Request-Id. It’s not exactly 16 bytes, but this is a very realistic scenario where guids are used in hot path. If you are writing a cute-kitten blog, might as well use Python instead..
sdrapkin··on Fast cryptographically safe GUID generator for Go
Guid/uuid is defined as a 16-byte structure. Are you questioning the “byte” part, or the “random” part?
sdrapkin··on Fast cryptographically safe GUID generator for Go
Fast guid/uuid generators are NOT a security risk. You want such generators to be as fast as possible, without compromising cryptographic strength.
sdrapkin··on Fast cryptographically safe GUID generator for Go
The vast majority of Golang developers would benefit from using Guid library instead of UUID library. It’s substantially faster in all cases, more secure (by 2^6) and has more functionality.

For random token-as-string generation Golang developers should be using https://github.com/sdrapkin/randstring instead of crypto/rand.Text (faster and more flexible).

sdrapkin··on Fast cryptographically safe GUID generator for Go
> This shouldn't really matter as your import paths are obviously different.

I'm aware of that, of course. Guid is intentionally named differently from "uuid" (both as a package and as a type) to ensure there is no confusion between them in code. It is not the goal of Guid to mimic/inherit all uuid APIs. Guid is its own package, with a different API surface and roadmap (ie. I'll borrow what makes sense and do things differently when it makes sense).

sdrapkin··on Fast cryptographically safe GUID generator for Go
You are correct - Guid very specifically and intentionally generates a structure of 16 random bytes. In decades of programming I've never needed a random 16-byte structure to have a "internal versioned structure". In very rare cases this is truly needed, bit-twiddling post-generation can cheaply fix it (but not the other way around). Which is why all these "versions" and "variants" in standard universally applicable libraries are a complete waste of entropy and cycles.
sdrapkin··on Fast cryptographically safe GUID generator for Go
Guid package generates guids/uuids. Your linked package generates variable length strings. These are different usecases (oh, and your benchmarks are inferior to https://github.com/sdrapkin/randstring). Nothing to argue about.
sdrapkin··on Fast cryptographically safe GUID generator for Go
cuid2 generates variable-length strings. If you want fast cryptographically strong string generation, I recommend https://github.com/sdrapkin/randstring. It will likely be faster than cuid2.
sdrapkin··on Fast cryptographically safe GUID generator for Go
It's on the roadmap (already implemented in a similar .NET library - https://github.com/sdrapkin/SecurityDriven.FastGuid).
sdrapkin··on Fast cryptographically safe GUID generator for Go
In case you missed it, "guid.Read()" is a much faster alternative to "crypto/rand". https://pkg.go.dev/github.com/sdrapkin/guid#Read
sdrapkin··on Fast cryptographically safe GUID generator for Go
IMHO "Guid" is just as well known (Wikipedia agrees: https://en.wikipedia.org/wiki/Universally_unique_identifier), and "UUID" was already taken by Google.
sdrapkin··on Fast cryptographically safe GUID generator for Go
Thanks for your feedback. If you are skilled in Golang, I suggest you review the code more thoroughly for a more accurate understanding (especially compared to what standard uuid does).
sdrapkin··on Fast cryptographically safe GUID generator for Go
It generates entropy 4kb-at-a-time (instead of on each call), and uses a cache-pool instead of single cache behind a lock (which is what standard uuid does in "RandPool=ON" mode).
sdrapkin··on Fast cryptographically safe GUID generator for Go
Much faster (~10x) than standard github.com/google/uuid package

I'm interested in feedback from the HN community.

sdrapkin··on I want XAES-256-GCM/11
Indeed. But FIPS is not the only problem. Both the McGrew/Viega spec and subsequent NIST spec of GCM mandate a 4-byte counter - any departure from that would be "no longer GCM".
sdrapkin··on I want XAES-256-GCM/11
GCM (ie. AES-GCM) has the following problems, which extended variants - those that deterministically randomize (key,nonce) pair - do not solve:

Inability to encrypt more than 64Gb with the same (key,nonce) pair.

Lack of commitment (whether key-commitment, or key+nonce+ad commitment).

If one is seriously considering breaking away from existing GCM standards to create yet-another-standard, such proposal would need to offer improvements in all areas (ex. a proposed standard for converting any AEAD into streaming chunk-based AEAD with practically unlimited message sizes under the same (key,nonce) and unlimited message counts.

GCM-256 is ubiquitous and is often the preferred choice for all the reasons mentioned by the author, but that very argument is what makes non-standard GCM with 11 AES-rounds silly.

In 2023 we should be working on new standards that "wrap" existing crypto-primitives (which are already implemented/available in countless hardware-accelerated libraries/APIs) to get additional features/benefits/capabilities - not musing about AES with 10+1 rounds or SHA-512-really-fast with 80-1 rounds..

sdrapkin··on CryptoRandom – .NET Random done right
Modern, fast, safe, cryptographically strong .NET replacement for Random and RandomNumberGenerator.
sdrapkin··on Login.gov encryption is badly designed
"OMG, you're totally right - if only the OP knew that scrypt ends with pbkdf2.."

Um, no. But thanks for playing. For those who wish to argue that everything that precedes PBKDF2 in scrypt should be considered as "key extraction", you should read NIST SP800-56c, also referenced by FIPS-140-2 Annex-D (tldr: scrypt does not fly). Welcome to USG infosec compliance.

sdrapkin··on Login.gov encryption is badly designed
The OP is referring to the OP-linked 18F writeup (you might want to read it), which says "Based on consultation with NIST we follow these steps..."
sdrapkin··on Maybe Skip SHA-3
The best (ie. fastest and safest) SHA2-family function is SHA-384. http://securitydriven.net/inferno/#Implementation%20Details
sdrapkin··on Why I've Retired My PGP Keys and What's Replaced It
"The process for encrypting a file: (3) SHA-256 hash the shared secret to generate a 64-bit IV."

"The process for decrypting a file: (4) Validate the IV against the shared secret hash and format version."

Does anyone else see a problem with the above? I do.

sdrapkin··on How the Textsecure Protocol Works
An important part of the Signal Protocol is Triple-DH. I did not find a good illustration of how it works, so I made one: https://twitter.com/sdrapkin/status/738419956371628033
sdrapkin··on Copy and paste-friendly Go crypto
.NET is covered: http://securitydriven.net/inferno/
sdrapkin··on Nonce misuse resistance 101
I've read the source too. You are strangely looking at EtM_CBC, which is not Inferno's primary mode. Inferno uses EtM_CTR for the "Encrypt" signature you cite. The raw CBC mode is already nonce-misuse-resistant (reveals common prefix), and thus is better than raw CTR from NMR perspective. If you want to critique Inferno's NMR properties, you should target its primary EtM_CTR primitive, rather than EtM_CBC.

"vulnerable to failure if the application uses fork()" - I strongly suspect that your comfort-zone is c/c++/Linux/*nix, and not .NET framework and Windows. You failure scenario does not apply to Inferno.

If CSRNG is "awkward to implement on some embedded platforms" then it is a platform problem, not Inferno's. Inferno is designed to take full advantage of plentiful (ie. high-quality/cheap/fast) cryptographically-strong randomness available to .NET framework on Windows.

You question Inferno's speed - performance is in the eye of the benchmark beholder - but I doubt you have run any (ie. this is likely FUD). Based on the benchmarks I've run, Inferno is very fast.

Inferno does not ignore nonces - it force-randomizes them internally to the maximum extent (320 bits of entropy). This creates a nonce-misuse-resitant design which eliminates user-supplied nonces, and does not break even under a faulty CSRNG producing a lot less entropy than it should.

sdrapkin··on Nonce misuse resistance 101
Nonce-exposing high-level crypto APIs are flawed by design. Most developers believe that they need low-level crypto APIs - in fact they get a kick out of coding against low-level crypto APIs. This is a dangerous fallacy/hubris. Most developers, in fact, should never touch low-level crypto APIs, and should only use high-level crypto APIs (or not touch crypto at all, which would make the digital world a safer place).

SecurityDriven.Inferno library is nonce-misuse-resistant by design (http://securitydriven.net/inferno/).

sdrapkin··on KeePass – questionable security
Additional evidence of inadequate .NET implementation:

There is a ton of code & pointless complexity to minimize the time sensitive data has to remain in plaintext in memory, and zeroing buffers asap. Clearly, the "process memory compromise" threat vector is taken very seriously by the authors.

Here's a KeePass function that generates a key: https://github.com/wrouesnel/keepass/blob/master/KeePassLib/...

Does anyone see what the problem is? Hint: disposing "ms" in addition to closing will not fix the problem.

There are ~ 59 instances of this mistake in the codebase. The author(s) seem to come from c/c++ background, and make all kinds of assumptions about how .NET works - except that .NET doesn't work the way they think it works.

The generation of the Master Key: https://github.com/wrouesnel/keepass/blob/master/KeePassLib/...

Note that "pbNewKey" can be sitting in memory forever.

TL/DR: KeePass memory protection is completely ineffective (I only speak for .NET implementation).

Page 1 of 2Next →