After some research it would seem that RSA with PSS padding is suggested to be used as its security properties are known to be good. The problem is that it is hard to have compatibility of signing algorithms, especially with such requirements.
What I'd like to achieve is to sign and verify across at least the following environments:
Botan
OpenSSL
Crypto++
Node.js (uses OpenSSL)
It might also be interesting to have compatibility on PolarSSL and others.
There is an example in the node.js crypto page about creating and verifying signatures. This works nicely, but I need compatibility with Botan EMSAx(SHA256), and really think that a signature should be padded for security with something like RSA-PSS. The Node example page only show 'RSA-SHA256' but there is no padding used.
The PSS padding can be achieved by using OpenSSL:
openssl dgst -sha256 -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:32 \
-sign rsa.key -out data.txt.sha256 data.txt
My test code looks something like this:
var s = crypto.createSign('RSA-SHA256');
var key = fs.readFileSync('rsa.key').toString();
s.update(message);
var signature = s.sign(key, 'base64');
but it produces identical output for identical input, which is not what I want, and is obviously not compatible with the C++ implementation I have which uses Botan.
If it is not possible to achieve compatibility with minimal effort, any suggestions on which algorithms to pick, I might put the effort in to try to contact the developers of these crypto-libraries, to see if there is any consensus on an algorithm to get implemented as a de facto standard. (Yes, I know this seems desperate.) Is there an ongoing effort like this?
You are currently using PSS signature format, while Node.js almost certainly uses PKCS#1 v1.5 compatible signatures - and if I look at the current code, Node.js seems to be restricted to those. One difference is indeed that PSS generated signatures contain a random component and PKCS#1 v1.5 compatible signatures do not.
Although PSS signatures are certainly preferred, it seems the only option for you is to either revert back to PKCS#1 v1.5 compatible signatures for Botan, or to implement PSS signatures in Node.js. PKCS#1 v1.5 signatures should still be safe, even though they have less desirable properties compared to PSS signatures.
Related
Do I need both MD5 and SHA-1 values to be sure the downloaded file is
a) Untouched by hackers. For example, when I need to download some app's .iso via torrents
and
b) Not corrupted during technical issues? For example, some unstable network connection during download.
Or, probably, SHA-1 value will be enough for both checks?
Also, is SHA-1 (without MD5) enough to be sure that some file downloaded years ago and stored somewhere on my HDD haven't degradated?
From a security perspective MD-5 is utterly broken.
SHA-1 is considered suspicious, and avoided for most uses if at all possible. For new projects: don't use it at all.
SHA-2 (aka SHA-256, SHA-512, etc.) is still widely used for fast hashes.
SHA-3 is the future since 2012, nothing is stopping you from using it already. I see little reason not to use it for new projects.
What's the problem with older ones:
Their resistance to finding collisions is below par: This is an attacker creating 2 contents that have the same hash. These are constructed at the same time. This problem is there for MD5 and SHA-1, and it's BAD, but requires the attacker creating both versions (and then they can do a switch at any time they want undetected).
Their resistance to length extension attacks is relatively weak. This is especially true for MD5, but SHA-1 and even SHA-2 to some degree suffer from it.
When is it not a problem: to ensure your disk has not produced an error: and hash will do, even a simple CRC32 will work wonders (and I'd recommend the simpler CRC check), or a RAID array, as these can fix errors, not just detect them.
Use both ?
Well if you have to find a collision on one hash and have that same set of plaintexts also produce a collision on another hash, is probably more difficult. This approach has been used in the past, The original PGP did something like it. If I'm not mistaken it had a number of things it calculated, one of them simply the length (which would prevent the extension attack above).
So yes, it likely adds something, but the way md5 and SHA-1 and SHA-2 work internally is quite similar, and that's the worrisome part: they are too much alike to be sure just how much it adds against a highly sophisticated attacker (think the level of the NSA and their counterparts).
So why not use one of the more modern versions of SHA-2, or even better SHA-3 ? They've no known weaknesses and have been peer-reviewed heavily. As such for any commercial level use, they should be more than enough.
Refs:
https://en.wikipedia.org/wiki/Length_extension_attack
https://en.wikipedia.org/wiki/Collision_attack
https://stackoverflow.com/questions/tagged/sha-3
I'm trying to implement RSA sign on Java Card version 2.2.1. I have implemented RSA 2048 and tested this successfully, but when trying to hash using the MessageDigest class, I'm unable to get the correct answer in response.
Here is my code:
MessageDigest md = MessageDigest.getInstance(MessageDigest.ALG_SHA, false);
md.reset();
md.doFinal(toSign, bOffset, bLength, tempBuffer, (short) 0);`
But I do not get the correct answer; neighther for ALG_SHA nor for ALG_MD5.
I'm wondering what the problem is. All samples I have seen use the same methods and parameters.
The Java Card 2.2.1 specification does not support SHA-256 (or any of the other SHA-2 message digests). It only supports SHA1 and MD5, two complete different cryptographic hash functions. Consequently, neither MessageDigest.ALG_SHA nor MessageDigest.ALG_MD5 will get you an instance of MessageDigest that could calculate the SHA-256 hash function.
Only Java Card 2.2.2 and onwards supports various SHA2 functions. In that specification, the MessageDigest class would also support
SHA-256: MessageDigest.ALG_SHA_256,
SHA-384: MessageDigest.ALG_SHA_384, and
SHA-512: MessageDigest.ALG_SHA_512.
So if you are lucky and your card actually supports Java Card 2.2.2, you could actually use those constants to obtain a proper MessageDigest object.
If your card does not support Java Card 2.2.2, then, of course, you can't use should not1 be able to use those constants. You could still check the manual of your card if it supports some proprietary implementation of the MessageDigest that also has support for SHA-256, though I highly doubt that.
1) Thanks to vlp for pointing out that there are actually cards that are Java Card 2.2.1 (or below) that seemingly support using the constants for SHA-2 algorithms introduced in the Java Card 2.2.2 API. This might just be caused by other implementation bugs and nobody seems to have tested if these algorithms actually work on those cards. See the JCAlgTest list for findings on that.
HTTP GET is one of the methods offered by open.epic for single sign-on. However, the documentation is a bit vague and doesn't give a good step-by-step process for decryption.
According to their documentation (note you'll have to create a login in order to access this link):
We use 128-bit AES, with the CBC cipher mode and PKCS7 padding (this is equivalent to PKCS5 for our use). We use an empty IV. Additionally, we use Microsoft’s key derivation algorithm as outlined in the remarks section here.
The remarks then outline an algorithm but nothing's done by example. Has anyone implemented this in node.js and could give a code example?
This took me a couple days, but I eventually came up with a node.js implementation. I'm using node version 4.7, with es2015 class syntax. I make use of the node-crypto library and only one external library -- bitwise-xor.
Also, one thing they don't tell you is the hashing algorithm required by the Microsoft derivation algorithm. I tried several before landing on sha1 as the correct algorithm.
You can find my implementation at this Gist.
I know the list of all hash functions is too long. I just want to know the most popular ones which are used in day to day IT practical tasks. I know MD5, SHA1, SHA2 (256 and 512) are really popular. Is there any other hash function I can add to these 5 algorithms?
I want to develop a hash Tool and I just want to include those algorithms that developers really need.
MD5, SHA-1 - Commonly used, used to be secure, but no longer collision resistant
SHA-2 - Commonly used, secure. It's a family of functions with different output size.
SHA-3 - Not yet specified, but will probably become popular after that. Wait for the spec. Will be a family of functions.
CRC32 - Not secure, but really common as checksum
MD4, RIPEMD160 - Haven't seen those for hashing files, but they're still around in some other contexts. MD4 is broken, some older members of the RIPEMD family are broken, but RIPEMD160 is still secure. Only place I've seen whirlpool is TrueCrypt's KDF.
TTH / TigerTreeHash - Used in some filesharing contexts, still secure but security margin grows thin
ED2K - Used in some filesharing contexts, MD4 based, broken collision resistance
Skein, Blake2 - Skein is a SHA-3 finalist, Blake2 is derived from one. Relatively fast in software and occasionally used but not really common. As a contributor to Blake2 I hope it gets more popular :)
Beyond the hashes you named CRC32 is really common, and TTH/ED2K are used in a filesharing context but rarely elsewhere. Haven't seen much of the other hashes in a file hashing context.
Most widely used (and defined in standards for SSL/TLS, OpenPGP, SSH) are:
CRC32 - simple checksum, used in ZIP, OpenPGP and number of other
standards.
MD2, MD5 - too old and weak MD5 - old and considered weak.
SHA1 - standard de facto, used almost everywhere (DSA algorithm is
used only with SHA1, that's also wide usage area).
SHA224/256/384/512 - should supersede SHA1, and is used with DSA keys
larger than 1024 bits, and ECDSA signatures
RipeMD160 - used in OpenPGP, and some X.509 certificates.
There are also other hash algorithms (you can get the full list on wikipedia), but most likely you'll never meet them in real life.
bcrypt and scrypt. These are meant for password hashing.
bcrypt has been around for quite a long time, and it's considered safe. scrypt is a newer one, and it applies some memory intensive operations to prevent brute-force attacks with GPU.
In case you just want to add hash functions in your tool, irrespective of security, then MD-4 and NIST SHA-1 and SHA-2 competition finalists can be implemented.
For newer and more secure hash functions, SHA-3 winner (Keccak) can be implemented.
NIST hash function competition
SHA-3
First you need to decide if you want fast, insecure hash functions, or slow, secure ones.
Of these the best are currently:
Fast: CRC32 on SSE4.2/armv7 HW, Murmur3, CityHash, FNV
Secure: SHA-3 (Keccak), SHA-2, BLAKE2
See https://code.google.com/p/smhasher/w/list for a testing framework of some popular ones.
[Edit note: prev. had bcrypt, scrypt as secure+slow hash functions, but they are just password hash functions]
I suggest you to study about DES and TDES, they do encryption with key and will be good choice for you if u need to encrypt/decrypt data with public / private key.
(A)RC4 used to fit the bill, since it was so simple to write. But it's also less-than-secure these days.
I'm wondering if there's a successor that's:
Code is small enough to write & debug within an hour or so, using pseudo code as a template.
Still considered secure, as of 2010.
Optimized for software.
Not encumbered by licensing issues.
I can't use crypto libraries, otherwise all of this would be moot. Also, I'll consider block algorithms though I think most are pretty hefty.
Thanks.
Honestly your best bet is to go use a crypto library. Its an already tested platform and when even the crypto libraries can/do have trouble with implementing the algorithms... Its better to use the pre-existing crypto libraries, its already tough enough to do encryption/decryption correctly using the API as it is as in this post on Coding Horror: Why Isn't My Encryption.. Encrypting?
Now I've gone to the Wikipedia article on Stream ciphers it might be worth going through the list of ciphers on the article, there has been several ciphers developed since RC4 in 1987, and to my very limited cryptography knowledge some of them seems like they might be more secure than RC4. You may also want to consider checking out the Wikipedia article on eSTREAM. There are several ciphers which are in the portfolio: HC-128, Rabbit, Salsa20/12, SOSEMANUK.
No cipher is easy to implement, especially symmetric ciphers and they never will be. There is a lot that can go wrong, and most programmers don't realize this. You need to do a lot more reading into this topic.
With block ciphers you must be concerned with the mode you use, and different modes fill different needs(But ECB is always the wrong choice). You must also be very careful about maintaining a unique IV for each message. If you are using a "password" as your key then you have to use a string2key function.
Stream ciphers don't have IV's or modes, and this actually makes things more difficult. A stream cipher function accepts only a key and the output is a "PRNG stream" that is infinity large. This stream of random data is then XOR'ed with your message. So if you use the same key, you will get the same PRNG stream. If an attacker knows the plain text of 1 message (or a part of a message) then he can XOR out the PRNG from the cipher text and then decrypt all other messages using that key in constant time O(1). For a stream cipher to be practically secure you can never reuse the same key.
I highly recommend that you pick up a copy of Practical Cryptography, which has a few chapters dedicated to Symmetric Cipher attacks. This book is straight to the point and doesn't require a lot of math. If don't really care about implementing your own then you can use a proven cipher implementation such as Jasypt which "just works" in a very secure way.