Wrapping mechanism for ECDSA keys - cryptography

I am using pkcs11interop to generate keys, and do wrap/unwrap. This is what I am using for my work
https://github.com/Pkcs11Interop/Pkcs11Interop/blob/master/src/Pkcs11Interop/Pkcs11InteropTests/HighLevelAPI/_24_WrapAndUnwrapKeyTest.cs
I can generate ECDSA p-256. But the problem is that I want to wrap/unwrap ECDSA keys and I do not know which mechanism value (CKM_???) should be used.
The sample above is using CKM_RSA_PKCS, and it is for RSA only.
IMechanism mechanism = Settings.Factories.MechanismFactory.CreateMechanism(CKM.CKM_RSA_PKCS);
I also tried with several CKM for wrap/upwrap here
http://wiki.ncryptoki.com/GetFile.aspx?File=%2fdocs%2fpkcs-11v2-20.pdf
but it still fails.
if you have any information about this, please help share with me. Thanks a lot!

Related

Apache Mina Client Public key authentication

apache mina sshd authenticate client signatures
I found this link, I have implemented the PublicKeyAuthenticator's authenticate method and using KeyUtils.compareKeys method to compare the public key of the user stored and the incoming key. But its not matching. What is the format of the key that needs to be stored in the local to compare against the incoming public key? I have been breaking my head on this for the last few weeks and couldnt solve this. Please help.
I think the key should start with -----BEGIN RSA PRIVATE KEY----- to be recognizable by Apache Mina.
If you are using putty gen key, which starts with PuTTY-User-Key-File-2: ssh-rsa, there should be some tweaks to be made to work with these files,
something like:
PuttyKeyUtils.DEFAULT_INSTANCE.loadKeyPairs(Paths.get(privateKey), FilePasswordProvider.of(this.pwd)))
put a breakpoint on compareKeys() in KeyUtils, you will be able to see the keys being compared and try to find their type. I had a similar problem and for me turns it was not able to compare OpenSshCertificate type of public key.

React native RSA encryption with a public PEM or SSLeay key

I am trying to find a working javascript library for react-native that will allow RSA public key encryption in PEM format.
I am not an expert in encryption and just starting out with react-native so please excuse me if i happened to miss something obvious.
So far i have tryed
react-native-rsa as recomended by this post
and
react-native-rsa-util.
I couldn't get react-native-rsa-util to work and react-native-rsa doesn't seem to accept public PEM keys but only keys in the JWK format.
The only reason i am not willing to use the JWK format is that i cannot find a PHP library that will decrypt the incoming message with a JWK key.
I would highly appreciate any help / pointers.
Thanks alot
I wrote a PHP library that supports JWT encryption/decryption with a lot of other useful features including compression.
All algorithms referenced in the RFC7518 and JWK/JWKSet are supported.
What you can do is convert your PEM key into JWK with my library:
<?php
use Jose\Factory\JWKFactory;
$jwk = JWKFactory::createFromKeyFile('/path/to/my/key.pem');
var_dump($jwk->getAll());
And to decrypt a JWT with your JWK and my library:
use Jose\Loader;
$input = 'eyJhbGciOiJS...';
$loader = new Loader();
$jwe = $loader->loadAndDecryptUsingKey($input, $jwk, ['RSA-OAEP-256'], ['A256CBC-HS512']); // The list of accepted key and content encryption algorithms depends on your needs
The variable $jwe is now JWE Object.
You can get the payload by calling $jwe->getPayload();
Do not hesitate to contact me on the dedicated Gitter channel if needed.

Send RSA public key over socket them import it for encryption [VB .NET]

I'm writing that generates public and private key pair, then send the public key over the socket to another programs to be used to encrypt string data.
I'm using RSA in VB.NET and I was able to generate the required keys:
My public key v+u4Lt4nyLXincU+wbReOTU3nwiTZ7MlFkA7cytLOjuviHrAdnaVAV8+WoFhy9nADGtk1K0OLAE1ZwGzt/kgUw==
My question is: is the public key enough for encryption by other users? and if so, how can I import it to RSA parameters to encrypt data?
Edit:
I used the following code in an attempt to import the public key but it failed:
Dim Parameters As New RSAParameters
Parameters.Modulus = encoder.GetBytes(publicKey)
RSA.ImportParameters(Parameters)
My question is: is the public key enough for encryption by other
users?
The answer is as so often: It depends.
The way you describe your proposed protocol this would be widely open to man-in-the-middle-attacks. Eve could just intercept the message on the wire and replace the key by her own.
From a theoretical point of view, it is sufficient to encrypt data. However, to be useful in real world scenarios, you have to use symmetric encryption as well.
So here is my advice:
Don't do your own protocols if you have to ask such questions. Never. Not once. Use Well known, established technology like TLS!
I had a similar project in VB.net, you will not be able to send messages of a large length because if you are using 2048bit RSA, the maximum size of data you would be able to send would be 245 bytes. https://security.stackexchange.com/questions/33434/rsa-maximum-bytes-to-encrypt-comparison-to-aes-in-terms-of-security
I used the RSA public key so each client would use AES encryption and pass their own keys which are encrypted with RSA, the server would then decrypt the key and use that to resolve data. This uses both asymmetric(RSA) and symmetric encryption(AES). Here is a link with a useful video that explains this when I was doing this project. https://www.youtube.com/watch?v=6H_9l9N3IXU&t=271s
The way I imported the keys was using the .toXMLString and .fromXMLString in the RSA CryptoServiceProvider. Here is a great link explaining it, probably doing a better job that I could. https://msdn.microsoft.com/en-us/library/system.security.cryptography.rsa.toxmlstring(v=vs.110).aspx
I found this page that was very useful for me here
Also I found that I was making the mistake of converting the encrypted byte array to string after encryption then back to byte array just before decryption. The last byte array didn't have the same size as the original.

Can one encrypt with a private key/decrypt with a public key?

[Disclaimer: I know, if you know anything about crypto you're probably about to tell me why I'm doing it wrong - I've done enough Googling to know this seems to be the typical response.]
Suppose the following: you have a central authority that wants to issue login cookies for a given domain. On this domain, you don't necessarily trust everyone, but you have a few key end-points who should be able to read the cookie. I say a few, but in practice this number of "trusted" partners may be large. The cookie doesn't contain much information - a username, a timestamp, an expiry, a random number. It should remain small of course, for performance reasons, even after encryption (within reason). Now, there are two security issues:
1) We don't trust every webserver on this domain with user data. For this reason, the ability to read the cookie should be restricted to these trusted partners.
2) While we trust these partners to protect our user's data, we'd still like the central point of authority to be unforgeable (again, within reason).
Now, if we generate a private RSA key for the authority and keep it secret, and distribute the public key only to the "trusted partners", we should be able to encrypt with the private key and have it readable by anyone with the public key. What I'm unclear on is, would it still be necessary to sign the message, or would the act of decrypting be evidence that it was generated with the private key? Is this any way in which this scheme would be better or worse than disseminating a symmetric key to all parties involved and using that to encrypt, while using the private key merely to sign? And of course feel free to tell me all the ways this is a stupid idea, but bear in mind that practical arguments will probably be more convincing than rehashing Alice and Bob.
Oh, and implementation pointers would be welcome, though one can find the basics on Google, if there are any "gotchas" involved that would be useful!
Nate Lawson explains here and here why you can't securely use the public key as a closely-held secret decryption key (it's a subtle point, and a mistake plenty of others have made before you, so don't feel bad!).
Just use your public key to sign for authenticity, and a separate symmetric key for the secrecy.
I've read enough on interesting attacks against public key systems, and RSA in particular, that I agree absolutely with this conclusion:
Public key cryptosystems and RSA in
particular are extremely fragile. Do
not use them differently than they
were designed.
(That means: Encrypt with the public key, sign with the private key, and anything else is playing with fire.)
Addendum:
If you're interesting in reducing the size of the resulting cookies, you should consider using ECDSA rather than RSA to produce the signatures - ECDSA signatures are considerably smaller than RSA signatures of an equivalent security factor.
In cryptography you are what you know. In your scenario, you have a central authority which is able to issue your cookies, and you want no other entity to be able to do the same. So the central authority must "know" some private data. Also, you want the "trusted web servers" to be able to access the contents of the cookies, and you do not want just anybody do read the cookies. Thus, the "trusted web servers" must also have their own private data.
The normal way would be that the authority applies a digital signature on the cookies, and that the cookies are encrypted with a key known to the trusted web servers. What your are thinking about looks like this:
There is a RSA modulus n and the two usual RSA exponents d and e (such that ed = 1 modulo p-1 and q-1 where n=pq). The central authority knows d, the trusted web servers know e, the modulus n is public.
The cookie is processed by the central authority by padding it into an integer c modulo n, and computing s = c^d mod n.
The trusted web servers access the cookie data by computing c = s^e mod n.
Although such a scheme may work, I see the following problems in it:
For basic security, e must be large. In usual RSA descriptions, e is the public exponent and is small (like e = 3). A small exponent is no problem when it is public, but since you do not want cookie contents to be accessible by third parties, you must make e big enough to resist exhaustive search. At the same time, trusted web servers must not know p and q, only n. This means that trusted web servers will need to compute things with a big modulus and a big exponent, and without knowing the modulus factors. This seems a minor point but it disqualifies many RSA implementation libraries. You will be "on your own", with big integers (and all the implementation issues known as "side-channel leaks").
Resistance of RSA signatures, and resistance of RSA encryption, have been well studied, but not together. It so happens that the padding is essential, and you do not use the same padding scheme for encryption and for signatures. Here, you want a padding scheme which will be good for both signature and encryption. Cryptographers usually consider that good security is achieved when hundreds of trained cryptographers have looked at the scheme for a few years, and found no blatant weakness (or fixed whatever weaknesses were found). Home-cooked schemes almost always fail to achieve security.
If many people know a secret, then it is not a secret anymore. Here, if all web servers know e, then you cannot revoke a trusted web server privileges without choosing a new e and communicating the new value to all remaining trusted web servers. You would have that problem with a shared symmetric key too.
The problem of ensuring confidentiality and verifiable integrity in the same type is currently being studied. You may look up signcryption. There is no established standard yet.
Basically I think you will be happier with a more classical design, with digital signatures used only for signing, and (symmetric or asymmetric) encryption for the confidentiality part. This will allow you to use existing libraries, with the least possible homemade code.
For the signature part, you may want to use DSA or ECDSA: they yield much shorter signatures (typically 320 bits for a DSA signature of security equivalent to a 1024-bit RSA signature). From the central authority point of view, ECDSA also allows better performance: on my PC, using a single core, OpenSSL crunches out more than 6500 ECDSA signatures per second (in the P-192 NIST curve) and "only" 1145 RSA signatures per second (with a 1024-bit key). The ECDSA signatures consist in two 192-bit integers, i.e. 384 bits to encode, while the RSA signatures are 1024-bit long. ECDSA in P-192 is considered at least as strong, and probably stronger, than RSA-1024.
You should use a digital sigantures scheme of some sort, or some other mechanism that is aimed to solve the integrity problem of your scenario.
The encryption itself isn't enough.
How would you know that the decrypted messege is what it should be?
Decrypting a cookie encrypted with the right key will surely provide a "valid" cookie, but what happens when you decrypt a cookie encrypted with the wrong key? or just some meaningless data? well, you might just get a cookie that looks valid! (the timestamps are in the range you consider valid, the username is legal, the random number is... uh... a number, etc.).
In most asymmetric encryption algorithms I know off, there is no built-in validation. That means that decrypting a message with the wrong key will not "fail" - it will only give you a wrong plaintext, which you must distinguish from a valid plaintext. This is where integrity comes to play, most commonly - using digital signatures.
BTW, RSA is long studied and has several "gotchas", so if you plan to implement it from scratch you better read ahead on how to avoid creating "relatively easy to break" keys.
Public keys are by definition, public. If you're encrypting with a private key and decrypting with a public key, that's not safe from prying eyes. All it says: "this data is coming from person X who holds private key X" and anyone can verify that, because the other half of the key is public.
What's to stop someone you don't trust putting public key X on a server you don't trust?
If you want a secure line of communication between two servers, you need to have all of those trusted servers have their own public/private key pairs, we'll say key pair Y for one such server.
Server X can then encrypt a message with private key X and public key Y. This says "server X sent a message that only Y could read, and Y could verify it was from X."
(And that message should contain a short-lived symmetric key, because public key crypto is very time-consuming.)
This is what SSL does. It uses public key crypto to set up a session key.
That being said, use a library. This stuff is easy to screw up.
The answer to your question "would the act of decrypting be evidence that it was generated with the private key", the answer is yes if the recipient can do simple validation of the data. Say you have "User name : John, timestamp : <number>, expiry : dd/mm/yyyy". Now if a wrong public key is used to decrypt, the probability that you will get "User name : <some letters>, timestamp : <only numbers>, expiry : ??/??/????" is zero. You can validate using a regular expression (regex) like "User name : [a-zA-Z]+, timestamp : [0-9]+, expiry : .... " and drop it validation fails. You can even check if the day is between 1 and 31, month is between 1 and 12 but you won't get to use it as regex will typically fail at "User name : " if wrong public key is used. If validation succeeds you still have to check the timestamp and ensure that you don't have a replay attack.
However, consider the following:
RSA public key crypto is not designed for bulk encryption of structured data as it can be exploited by attacker. public key crypto is typically used in 2 ways: 1) for securely transporting the symmetric key (which by definition has no structure) which will be used in bulk encryption; this is done by encrypting the symmetric key using the public key and 2) digitally signing a document by encrypting not the document but the hash of the document (again something which has no structure) using the private key. In your case you are encrypting the cookie which has a definite structure.
You are depending on the public key not getting into the hands of the wrong person or entity.
public key encryption is about 1000 times slower that symmetric key encryption. This may not be a factor in you case.
If you still want to use this approach, and are able to distribute the public key only to the "trusted partners", you should generate a random session key (i.e. symmetric key), encrypt it using the private key and send to all recipients who have the public key. You then encrypt the cookie using the session key. You can change the session key periodically. More infrequently you can change the public key also: you can generate a new public/private key pair and encrypt public key with the session key and send it to all recipients.
I presume you trust the 'trusted partners' to decrypt and verify the cookie, but don't want them to be able to generate their own cookies? If that's not a problem, you can use a much simpler system: Distribute a secret key to all parties, and use that to both encrypt the cookie and generate an HMAC for it. No need for public key crypto, no need for multiple keys.
As an alternative to your key distribution approach, which may or may not be suitable in your application, consider using Kerberos, which uses symmetric key encryption, a single highly protected bastion server that controls all the keying material, and a clever set of protocols (See the Needham-Schroder protocol)

Encrypting a file with RSA in Visual Basic .NET

I'm just getting started with Visual Basic .NET and I'm currently stuck on the following problem: how can I encrypt/decrypt a file with asymmetric encryption?
Essentially, I'm trying to figure out how I can write the following pseudocode in VB:
Function EncryptFile(path_to_file_to_encrypt, public_key)
file = ReadFile(path_to_file_to_encrypt)
encrypted_file = Encrypt(file, public_key)
SaveToDisk(encrypted_file, "C:\Encrypted\encryptedfile.xxx")
End Function
Function DecryptFile(path_to_encrypted_file, private_key)
encrypted_file = ReadFile(path_to_encrypted_file)
file = Decrypt(file, private_key)
SaveToDisk(file, "C:\Decrypted\file.xxx")
End Function
The file I'm encrypting/decrypting is an Access database file (i.e. binary), if that makes any difference.
I understand there are containers for private keys, but it looks like the MSDN tutorial is sufficient for me to figure this bit out. I assume I can hard-code the public key in my code (it won't be changing).
Any help would be appreciated!
Usually, an RSA "key encryption key" is used to encrypt a "content encryption key" for a symmetric algorithm. That content encryption key is used to encrypt the file.
Protocols like SSL, S/MIME, and PGP can use this approach (sometimes called key transport). Asymmetric cryptography is very, very slow compared to symmetric algorithms.
Something like Chilkat's S/MIME library for VB.NET could handle this task.