I need some help with this lib. Fetching the following examples code BouncyCastle and I do not understand how this works.
My code: http://pastebin.com/RieDfUd9
Dictionary: chain[0], is sender cert.
conv, is the receiver cert.
My problem is this, I need to encrypt an email using smime with the public key personnel which I am sending the email. At the moment in my test environment I have access to both certificates. But in a production environment I will have only access to my certificate (who is sending) chain [0], and the public key of those who receive. I need encryptar email so that I can open with the public key of who is reading (and which was used to encrypt the message).
I already tried several ways, but I always have problems when decrypting.
You cannot do that. You will have to store the cert instead of just the public keys.
When a mail client receive a email, it has to know which private key to use to decrypt it - or it will just fail to decrypt.
How does the mail client knows which private key to use? Because recipient information is also in the encrypted mail.
You can't just encrypt your data encryption key with any random public key and hope the receiver knows which key can be used to decrypt it.
That's why the BouncyCastle API takes a certificate instead of a key.
You can more read about the details of SMIME encryption here:
https://security.stackexchange.com/questions/45222/smime-email-decryption-key-with-openssl
This link has more about how the decryption process is done for multiple recipients:
SMIME decryption for multiple recipients
Related
I am generating JWT using Node.js with require('jsonwebtoken') using public key which is generated by puttygen tool in windows. Then i will pass that token to other application in headers. The Other application is not developed in Node.js. Using java I need to validate the token with public key. But none of the sites i found a valid sample to verify using public/private key.
Can any one please provide me steps how i can load public/private key in java and verify jwt token. Please provide me examples if any you have. Thanks in advance.
Sample public key (public.pem) :-
---- BEGIN SSH2 PUBLIC KEY ----
Comment: "rsa-key-20160721"
AAAAB3NzaC1yc2EAAAABJQAAAQEAhk1i7Jwz2M6zakReDgg0NkVPn1kK1R8qAp2p
Ayh0eUPCb2XICDDVRnpUIK7/4k4dlLeeSi10TwwXe85zZ0gXcNMIOpnEKIWcnqJM
ctbYwyrl2tAb/tKjvBCvHMA9ZnfNADkN6reBZq8u7kYJ3bF9PxvS3QM+vgJ8/8ZS
qkRWcsmRZdq+wthwGt43J3NSKFfhMVP08/V/hTASq06vvFYApHsEH6zLxNNQ63Tt
Bzedh+C5efyqYqEVqnA7S9bXimyY2ViqpqFTx1lM9dV+12dSOxd7CQzX8eo00Phi
EAnY2hfoTooUeCO3/L6YavRl+CXgjhvA9mg4QO554qI1YCUvBw==
---- END SSH2 PUBLIC KEY ----
Node JS code:-
var privateKey = fs.readFileSync("public.pem");
var userData = {username:'John'};
var token = jwt.sign(userData, privateKey);
Java Code:-
Needed java code which can verify above token using above public key.
Cryptographic operations are independent of programming language. You can perfectly generate a JWT in nodeJS and verify in Java.
JWT is digitally signed with the private key and signature is verified with public key. In case of HMAC symmetric keys, the key to sign and verify is the same.
Use a JWT library for Java like https://github.com/jwtk/jjwt
Jwts.parser().setSigningKey(key).parseClaimsJws(compactJws);
In the page you can see the supported algorithms.
Putty uses its own key format. Java does not supports it. You need to export the Putty SSH2 key to the OpenSSH format. See
How can I read RSA keys in Java?
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
We are building a chat client (something like Whatsapp, etc.) for sending and receiving private messages. For the sake of privacy we decided to encrypt and decrypt the messages upon arrival and sending.
I figured we could use RSA private and public keys for encryption. I understand that we usually need two pairs of keys, one of which residing on the server and one on the phone. This brings up some questions which I'm asking here.
How to generate a key pair in android?
How should they be stored?
Do I need different key pairs for every user on the server as well as on the clients?
Please feel free to add any useful information for I am a complete newbie in security.
The most commonly used encryption/decryption technique is AES. You can find more information Visit http://en.wikipedia.org/wiki/Advanced_Encryption_Standard?
You simply need to define a KEY(anything like for example: 25346483936) which will be common both at mobile as well as server end along with an IV_Vector which is required for Cryptography it will be more clear from the code below.
Note: The length of the key must be equal to IV_Vector array size, it is 16 in the below example. Now using the encrypt method you can encrypt any information before sending it to server over a non-secure network. Similarly you can decrypt information received from server using DecryptData class.
public class Constants {
// encryption/decryption
public static String AES_KEY = "0366D8637F9C6B21";
public static byte[] IV_VECTOR = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
}
/**
* This class is used to decrypt an encrypted string value.
*
* #author kthakur
*
*/
public class EncryptDecrytData {
/**
* This method is used to encrypt a string value.
*
* #param text
* - string value to be encrypted.
*
* #return result(encrypted string) as String
*
* #throws Exception
*
*/
#TargetApi(8)
public static String encrytData(String text) throws Exception {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
byte[] static_key = Constants.AES_KEY.getBytes();
SecretKeySpec keySpec = new SecretKeySpec(static_key, "AES");
IvParameterSpec ivSpec = new IvParameterSpec(Constants.IV_VECTOR);
cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
byte[] results = cipher.doFinal(text.getBytes());
String result = Base64.encodeToString(results, Base64.NO_WRAP|Base64.DEFAULT);
return result;
}
/**
* This method is used to decrypt a string value.
*
* #param text
* - string value to be decrypted.
* #return result(decrypted string) as String
*
* #throws Exception
*/
#SuppressLint("NewApi")
public static String decryptData(String text)throws Exception{
byte[] encryted_bytes = Base64.decode(text, Base64.DEFAULT);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
byte[] static_key = Constants.AES_KEY.getBytes();
SecretKeySpec keySpec = new SecretKeySpec(static_key, "AES");
IvParameterSpec ivSpec = new IvParameterSpec(Constants.IV_VECTOR);
cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
byte[] decrypted = cipher.doFinal(encryted_bytes);
String result = new String(decrypted);
return result;
}
}
You will need a central server which provides certificates for each user to authenticate users (otherwise you will always be vulnerable to a man in the middle attack). So for two users (Joe and Sally), there will be three certificates: 1) the certificate authenticating your central server, 2) the certificate authenticating Joe and 3) the certificate authenticating Sally.
So when Joe wants to initiate communication with Sally the following should happen:
Joe requests Sally's public key from the central server.
Joe authenticates the server via the server's public key (by checking the digital certificate).
Joe uses the server's public key to encrypt a shared secret key and then sends the encrypted shared secret key to the server.
Only the server can decrypt Joe's shared secret key and thus uses this shared secret key to encrypt (via Symmetric Cryptography) Sally's public key and sends Sally's public key, encrypted via Joe's proposed shared secret key, to Joe.
Joe now has Sally's public key; authenticated because it came from an authenticated server.
Joe sends a request to Sally to initiate communication identifying themselves as "Joe" along with a digital certificate.
Sally authenticates "Joe" via the central server.
Sally retrieves Joe's public key in the same way that Joe obtained Sally's public key from the central server.
Sally sends a shared secret key to Joe.
Sally uses Joe's public key to encrypt a multi-part message which includes 1) the shared secret key and 2) a digital certificate encrypted with Sally's private key.
Joe receives Sally's encrypted message (which only Joe can decrypt since it was encrypted with Joe's public key).
Joe decrypts the message and receives Sally's proposed shared secret key.
Joe receives Sally's digital certificate, encrypted with Joe's public key, and attempts to decrypt with Sally's public key obtained previously from the central server.
If Joe successfully decrypts the digital certificate, then Joe can be assured that Sally is the one who proposed the shared secret key.
Joe sends an acknowledgement of the shared secret to Sally via symmetric cryptography, using the shared secret key.
Sally receives Joe's acknowledgement via Sally's proposed shared secret key.
Sally and Joe can now communicate back and forth using symmetric cryptography via Sally's originally proposed shared secret key.
So why is all of this necessary? First, you need a "trusted" broker (that's the central server). Otherwise you can never be sure who you are communicating with. You may ask: why does Sally need to sign her shared secret key when only Joe can decrypt it anyway (if Sally uses Joe's public key to encrypt)? The reason is that anyone can encrypt a shared secret key via Joe's public key! Therefore if Joe receives an unsigned shared secret key, he may start communicating with a man in the middle who simply generated a shared secret key using Joe's public key. Just as Sally needs some confirmation that Joe is the actual entity trying to communicate with her, Joe needs some assurance that the shared secret key he receives is actually from Sally (hence why she needs to sign with her private key).
RSA is not safe!!! Given enough traffic, it is possible to decrypt messages encoded by RSA. Thus, you should have a protocol in place for periodically updating public/private keys used for authentication. This is simple for users: your central server will hold the public keys for each user. Periodically your server should request that each user generate a new private/public key pair and send the public key to the server to be updated (this communication can be done via the previous private/public key used by each user).
It's a little more "difficult" for the central server itself. If your central server wishes to change its private/public key (authenticating the server), then it needs to communicate with every user to make each user aware of the change. When a user changes his/her private/public key, it's a one-to-one communication (just between the user and the server) but when the server wants to change its private/public key, it must communicate with all users!
Caveat:
I don't claim that what I proposed above is the "canonical" pattern. What I claim, is that if you follow the above, you will will ensure both authenticity and integrity. I.e. you can be guaranteed to be communicating with the entity the central server considers to be "Joe" and "Sally" and you can guarantee that only Joe and Sally can communicate because no one, including the central server, knows the shared secret key used by Joe and Sally to communicate (except for Joe and Sally of course).
There are many encryption/decryption algorithms such as Data Encryption Standards (DES), Playfair, etc., etc.
You may use those. And if you like, make your own algorithm. I once made a messenger app and I made my own algorithm for encryption/decryption.
You may also choose to have a symmetric or asymmetric key algorithm... Keep working, messengers have a nice scope.. :)
I have trouble understanding exactly how RSA works. Many examples and definitions attempt to explain but use a vague context.
So here is what I want to do:
I have a server that uses RSA and has a private and public key. From what I understand, upon connection the server sends the public key to the server in an unencrypted manner.. some kind of handshake if you will.
Further traffic would then occur in an encrypted fashion. To establish this fashion how would I be able to both encrypt what the client sends, and decrypt what the client receives (from client-sided perspective).
On server side encrypted data gets decrypted by the private key but I can't decrypt data in the client without that private key... that I can't have in the client because it's secret.
This confuses me, am I missing something obvious or is there need of a second private key?
Thanks in advance!
As you have already pointed out is RSA an asymmetric encryption scheme, that means:
c = E(pub_key, m) // ciphertext = encryption(public key, message)
m = D(pri_key, c) // message = decryption(private key, ciphertext)
In contrast a symmetric encryption scheme (such as fore example AES) works the following:
c = E(key, m)
m = E(key, c)
In other words the same key is used for encryption and decryption.
And that is where the asymmetric cryptosystem comes into play. It allows to parties to securely exchange a secret key for symmetric encryption.
So basically how a primitive (but very vulnerable!) key exchange could look:
server sends to client his public key pub_key_S
client sends to server his public key encrypted with the server's public key c = E(pub_key_S, pub_key_C)
server decrypts c with his private key pub_key_C = D(pri_key_S, c)
server generates a new random symmetric secret key key_CS
server encrypts the newly generated key with the client's public key c = E(pub_key_C, key_CS)
server sends c to the client
client decrypts ciphertext with his private key pri_key_C key_CS = D(pri_key_C, c)
Now Client and Server have a shared secret key key_CS which they can use to securely communicate for the ongoing session.
Such a protocol is in practice quite a bit more complicated, including certificates, digital signatures, hashcodes and so on. The probably most widely used protocol is SSL or TLS. (for in example https).
I recommend you to check out that link if you are interested in the details of such a protocol.
First read this article. Then you should know that usually asymmetric algorithms using for exchanging passwords and electronic signs. So the best way in client-server encryption is to generate common encryption key (with RSA or Diffie–Hellman key exchange), and then use any of symmetric algo (AES for example) to encode data between server and client.
I'm working on project which is required SSO implementation between WebShpere and PHP web application.
However after i take a look at possible ways to implement SSO i find the LTPA token which is used to implement SSO between different IBM technologies.
but LTPA token 2 is encrypted cookie file. which i should decrypt if i want to use information inside this file such as (userid, username, email ... etc).
i have make deep search about LTPA token 2 and below is the best definition i find from IBM.
LTPA2 signatures are generated using SHA-1 as the hash algorithm, and
RSA (1024-bit key) as the encryption algorithm. After the digital
signature has been attached, the user data and signature are encrypted
with a 3DES or AES key obtained from the LTPA key file (refer to
“Consuming LTPA tokens” and “Generating LTPA tokens”).
But i'm still trying to decrypt this token with no luck.
Any help ?
The Alfresco project did this. Take a look at this blog post for pointers, including working code.
To clarify things, the contents of LTPA tokens are strings that are more or less like "uid=user,cn=users,ou=myorg,dc=com#ldaprealm%timeout%[RSA signature]", encrypted with the shared AES key and encoded with Base64. LTPA v2 will not use 3DES, but only AES. So what you need really to do is to AES decrypt the cookie, and you can already read the username. You don't have to verify the RSA signature.
Why do you need to decrypt it from file? Isn't the token passed along with the calls that you made? When passed, LTPA token is encoded via Base64 and you can easily decode it. Below is an example of how to obtain information from token:
import javax.security.auth.Subject;
import javax.xml.bind.DatatypeConverter;
import com.ibm.websphere.security.cred.WSCredential;
import com.ibm.wsspi.security.token.Token;
Subject subject = ...; // obtain current JAAS subject
Set<?> publicCredentials = subject.getPublicCredentials();
for (Object credential : publicCredentials) {
if (credential instanceof Token) {
System.out.println(DatatypeConverter.printBase64Binary(((Token) credential).getBytes()));
System.out.println(((Token) credential).getName());
System.out.println(((Token) credential).getUniqueID());
System.out.println(((Token) credential).getAttributeNames());
}
}
Does anyone know if it is possible to load a KeyStore so that it only prompts for the password for the given alias?
Example:
In my key store i have two private keys: Alice's Encryption Certificate and Bob's Encryption Certificate.
When i load my key store:
keyStore = KeyStore.getInstance("Windows-MY", "SunMSCAPI");
keyStore.load(null);
I am prompted for both Alice's and Bob's key store password. Once they are entered i can use getKey("Alice's Encryption Certificate", null); to retrieve Alice's private key. My keys are protected by Entrust's Security Provider, it is who prompts me for the passwords upon loading the key store. If i do not enter Bob's password and try to get his key it will return null, which is fine, but i would like to avoid the password prompt.
Is it possible to somehow specify that i only want Alice's key before loading the key store so i am never prompted for Bob's password?
Thanks.
We had the same issue and couldn't find a way to do it. Basically, you are asking if there is a way to load the keystore partially. It makes things more complicated that MSCAPI provider ignores any password you provide.
We get around the issue by storing only one key With MSCAPI keystore. It turns out this works better with the security model of Smartcard also.