RSA keyczar and js - java

I've implemented a security system in my app with RSA.
I've generated the public and private keys using Keyczar Tool. Using just keyczar I can encrypt with public key and decrypt with private key with no problems at all.
I want to encrypt some data in JS and then pass it to Java. For this I'm trying to use this library (https://github.com/ziyan/javascript-rsa) but I'm not being able to encrypt the data or at least not encrypting the data correctly (it's bigger than with keyczar).
How can I encrypt with this tool using my public key? Can anyone help me?

There is not a javascript client for keyczar, so if you want to produce ciphertext consumable by keyczar.
Look at the keyczar public key format you will need to provide the public key info from your server to your javascript encryptor.
http://code.google.com/p/keyczar/wiki/RsaPublicKey
Alternatively, it looks like your javascript library will read PEM format. You can use the KeyczarTool to export your public key in PEM format with the export.
Look at the Keyczar ciphertext format for rsa
http://code.google.com/p/keyczar/wiki/CiphertextFormat
You'll need to prepend the header to your ciphertext generate with the javascript.
Technically you need to produce a keyhash to append a proper header, but a given header will always be identical for a given key regardless of the ciphertext, so you could just provide it with your public key generated by the java keyczar code.

Related

Decrypting with same public key used for encryption in Java

I have a public key which is used to encrypt some binary data. How can I write the code that can decrypt this data with the same public key ?
You can't - the whole point about public/private-key-cryptography like RSA is that when you encrypt some data using a public key you can only decrypt it using the matching (!) private key. So without the proper private key you won't be able to recover your AES-key and you won't get back to your cleartext.

Java send PublicKey to PHP and encrypt data

So I have a PublicKey in Java, and I need to send a post request to the server with the key in it, then read the key server side, and send some data encrypted with it!
I succeeded at:
Generating the keypair (duh)
Encrypting and decrypting data with it in the Java program
Maybe: making a pem formatted key from it, I'm not sure
String phpPublic = ("-----BEGIN PUBLIC KEY-----"+Base64.encodeToString(MainActivity.instance.rsa.readPublicKeyFromFile(MainActivity.instance.rsa.PUBLIC_CLIENT_KEY_FILE).getEncoded(),Base64.DEFAULT)+"-----END PUBLIC KEY-----");
I think this does it, but I'm not sure! And would it be the same process to convert private keys to pem, just to make PUBLIC -> PRIVATE in the header and footer.
I don't know if converting to pem is really necessary, if it's not, please suggest a better way to do it.
This is how I do it in PHP, but I'm 99% sure it is wrong
$PubKey = openssl_pkey_get_public($publicPem);
$encrypted;
openssl_public_encrypt($toEncode, $encrypted, $PubKey);
echo $encrypted;
can you post a sample key?
in lieu of that i do think you'd have better success with phpseclib a pure php rsa implementation. it supports a lot more key formats than openssl does and it'll auto detect the type too.
example:
<?php
include('Crypt/RSA.php');
$rsa = new Crypt_RSA();
$rsa->loadKey('...');
$rsa->setSignatureMode(CRYPT_RSA_SIGNATURE_PKCS1);
echo $rsa->encrypt('whatever');

BouncyCastle: Extract public key informationfrom Certificate Signing Request

I am using Bouncy Castle library in Java for reading CSR. I need to extract the public key information from CSR. I can see that openssl is able to extract required information from CSR.
I can't find any way to do this in BouncyCastle. I have been able to read PKCS10CertificationRequest object from the CSR. I have seen examples using SubjectPublicKeyInfo for extracting public key. But the code relies on the fact that algorithm of public key is already known. I can do a "instanceof" operation for various algorithm parameters and match but I think there would be something better. I want to derive the algorithm from CSR itself. I tried to find this information but couldn't find anything related to this.
Thanks for help.
Solution is to create a new wrapper around the PKCS10CertificateRequest like this:
JcaPKCS10CertificationRequest jcaCertRequest =
new JcaPKCS10CertificationRequest(pkcs10CertRequest.getEncoded()).setProvider("BC");
This class has the getPublicKey() method.
PublicKey publicKey = jcaCertRequest.getPublicKey();

Help verifying RSA signed text with Python

Using Java I have created RSA keypairs. Using Java I can use these keys to sign and verify some text. I can also "export" these keys in PEM format and load them into a Python test script. Once in the Python script, I can use these keys to sign and verify some text using M2Crypto.
I have not yet been able to verify in Python the signature I created in Java.
Right now I am just trying to get cross-platform signing and verifying to work.
Here is Java snippet:
Signature sig = Signature.getInstance("MD5WithRSA");
sig.initSign(key.getPrivate());
sig.update("This is a message.".getBytes("UTF8"));
byte[] signatureBytes = sig.sign();
return Base64.encodeBytes(signatureBytes, Base64.DO_BREAK_LINES);
Which generates:
PIp4eLhA941xmpdqu7j60731R9oWSNWcHvwoVADKxABGoUE02eDS0qZ4yQD2vYBdRDXXxHV4UjtW
YQwv9nsOzCBWeDQ0vv6W0dLVfTBuk79On7AALuwnTFr8s0y5ZN5RINvPPR60mwONav26ZbPj4ub3
NZqUS/zkqyO8Z8D2zUjk0pqAhWDGbFBaWPQJBPOY9iRt8GlsAUkGfYGeIx9DNU8aiJmQ3NnUHbs4
5NEr3xydbNJjwK96kkNJ9vyKZRfnNd4eW2UllPiwJSRQgefCQfh79ZuiYeQEuk3HMh7Si4iYl7uU
rWCgYFl4fGV1X/k+BSHR4ZZFWGQ3IPfafYHyNw==
And here is the public key:
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAg+N7xQHVHU3VHMZ9VGFdUf6ud3rAL8YS
sfWv2zFMnKAjh6XacwDGX6jJR/0/pyDriRGw/uodBDSFvgn9XEM/srMYtbJ1KQ9R9ChDifixF3Hx
yzbzPRvFoEfZnS/63+d1r0wnafz7xx0eDEYE3TgRKTMikwOsuIOFWa7GhA4BvP7ad79bI5ORJdLu
9Je+k+4dbt0xk2t7YopxYmyU+4zhZMxuthJTr69rXgqhgsCRdK6kFIGm3YuJ1WQcci8OVwH+3o7F
XzJHpSTxH57m6PX5lXaywIDCbUauTpBV3w+0vTeGI/2o+U40qhLBkpZT9GSVKxgXl5a0XxrkwTGn
61XZqQIDAQAB
-----END PUBLIC KEY-----
Then in Python the key is loaded and the signature is attempted to be verified:
from M2Crypto import RSA, EVP
pub_key = RSA.load_pub_key('public_key.pem')
verify_evp = EVP.PKey()
verify_evp.assign_rsa(pub_key)
verify_evp.verify_init()
verify_evp.verify_update("This is a message.")
if verify_evp.verify_final(sig_string.decode('base64')) == 1:
print "Good"
else:
print "Bad"
And this does not verify. I suspect it is some leading or trailing characters or encoding weirdness that I don't understand.
I have no particular attachement to M2Crypto and have played a bit with the gdata.tlslite modules as well.
Please note that the keys are working, and that the text and signature above verify in Java, and the keys (public and private) can be used within Python to sign and verify text. The problem is somewhere in how Java-generated signature and/or the message text is getting into the Python code.
What am I doing wrong?
M2Crypto.EVP defaults to 'sha1' (SHA1) and you're using MD5WithRSA. I think you should switch SHA1WithRSA (MD5 is a very weak algorithm).

PKI verification across Java and Python

I am trying to implement a PKI verification scheme, where a message string is signed with a private key on server, the signature is stored on the client along with the message string. The client then verifies the signature using a public key.
The restrictions of my environment are, the server is Google App Engine and the client is a Java program. I have played with Java-only and Python-only solutions of PKI verification and got them to work, however when doing one operation in Python and another in Java is posing problem, mainly due to Key file format restrictions and my limited understanding of cryptography terminology.
One of the biggest limitations is crypto support in GAE. The only library supported is PyCrypto and this library can't read public/private keys stored in PEM, DER or X509 formats. As far as I could find, only M2Crypto supports reading from these files, but it can't be used inside GAE because it's a wrapper around openssl, so not a pure python solution. Even if I could find a way to translate the public/private keys from PEM/DER/X509 to the format that PyCrypto understands, that will work for me. But I couldn't find any way to do it. Any ideas there?
I found one possible solution in the form of tlslite. tlslite could read a private key from PEM file and create a signature. Here is the code.
from tlslite.utils.cryptomath import bytesToBase64
from tlslite.utils.keyfactory import parsePEMKey
s = open('private.pem').read()
key = parsePEMKey(s)
doc = 'Sample text'
bytes = array('B')
bytes.fromstring(doc)
print bytesToBase64(key.sign(bytes))
The corresponding Java code I used to verify the signature is.
String signAlgo = "SHA1WithRSAEncryption";
// read public key from public.der
byte[] encodedKey = new byte[294]; // shortcut hardcoding
getAssets().open("public.der").read(encodedKey);
// create public key object
X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(encodedKey);
KeyFactory kf = KeyFactory.getInstance("RSA");
PublicKey pk = kf.generatePublic(publicKeySpec);
// read signature (created by python code above)
byte[] encodedSig = new byte[345];
getAssets().open("signature.txt").read(encodedSig);
byte[] decodedSig = Base64.decodeBase64(encodedSig);
// Do verification
Signature verifyalg = Signature.getInstance(signAlgo);
verifyalg.initVerify(pk);
verifyalg.update(message.getBytes());
Log.d(TAG, "Verif : "+verifyalg.verify(decodedSig));
The verification fails.
I suspected if the tlslite is using different algorithm for signature creation than what the java code expects.
So I tried to find that out.
On python side
print key.getSigningAlgorithm()
gave me
pkcs1-sha1
on Java side, I tried to find all supported algorithms with this code:
Set<String> algos = java.security.Security.getAlgorithms("Signature");
for(String algo : algos) {
Log.d(TAG, algo);
}
That gave me
MD4WithRSAEncryption
RSASSA-PSS
SHA1withDSA
SHA1withRSA/ISO9796-2
1.2.840.113549.1.1.10
SHA512withRSA/PSS
MD5withRSA/ISO9796-2
DSA
SHA512WithRSAEncryption
SHA224withRSA/PSS
NONEWITHDSA
SHA256withRSA/PSS
SHA224WithRSAEncryption
SHA256WithRSAEncryption
SHA1withRSA/PSS
SHA1WithRSAEncryption
SHA384withRSA/PSS
SHA384WithRSAEncryption
MD5WithRSAEncryption
I tried all the SHA1 values on the Java side. But none helped to verify the signature generated by tlslite with pkcs1-sha1 algo. Any idea about this mapping?
These are different operations. In Python, you need to use hashAndSign. The default happens to be SHA1 hash.
Keyczar should work fine on App Engine, and is available in both Java and Python flavours.

Categories

Resources