aspose file tools*
The moose likes Security and the fly likes Help to decrypt string containing RSA public key Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Engineering » Security
Bookmark "Help to decrypt string containing RSA public key" Watch "Help to decrypt string containing RSA public key" New topic
Author

Help to decrypt string containing RSA public key

Duran Harris
Ranch Hand

Joined: Nov 09, 2008
Posts: 598

Hi all,

This is the first time ive been exposed to cryptography and I need some help...
In my Java application, have a Base64 string that represents a Public Key generated by the C# bouncy castle API. (The data was encrypted with the private key).
The problem I am having is that I cannot for the life of me figure out how to recreate the Public Key from the Base64 string that I have.I downloaded the Jakarta Commons Codec to decode the string into a byte[], but I can't figure out which classes in Bouncy Castle I should be using?(Please keep in mind that my application needs to run on Java 1.4)

This is what i have come up with so far:



===>SCJP 1.5(72%)<===
==>SCWCD1.5(76%)<===
Ulf Dittmer
Marshal

Joined: Mar 22, 2005
Posts: 41884
    
  63
Check out new SecretKeySpec(byte[], String).


Ping & DNS - my free Android networking tools app
James Sabre
Ranch Hand

Joined: Sep 07, 2004
Posts: 781

Ulf Dittmer wrote:Check out new SecretKeySpec(byte[], String).


Not really applicable if the OP has a Public Key! The OP would more likely need to use X509EncodedKeySpec.

I'm not convinced that that is a representation of an RSA (or even DSA) public key. I would need to see the C# code before I could say what it actually does represent.


Retired horse trader.
 Note: double-underline links may be advertisements automatically added by this site and are probably not endorsed by me.
Pat Farrell
Rancher

Joined: Aug 11, 2007
Posts: 4658
    
    5

I'd change the requirements so you can run on a modern Java.

Most of the time, folks use the APIs in the JCE to handle all the text to String to ASN.1 to octet stuff. The ASN.1 stuff is particularly ugly.

I seriously doubt that looking at the C code that does the ASN.1 mangling will help, as ASN.1 itself is amazingly complex for the tiny amount of useful work that it does.

Pat
James Sabre
Ranch Hand

Joined: Sep 07, 2004
Posts: 781

Pat Farrell wrote:I'd change the requirements so you can run on a modern Java.

Most of the time, folks use the APIs in the JCE to handle all the text to String to ASN.1 to octet stuff. The ASN.1 stuff is particularly ugly.

I seriously doubt that looking at the C code that does the ASN.1 mangling will help, as ASN.1 itself is amazingly complex for the tiny amount of useful work that it does.

Pat


I don't think anyone is suggesting (certainly not me) that it would make sense look at the ASN.1 byte representation. To quote the OP "have a Base64 string that represents a Public Key generated by the C# bouncy castle AP" and my experience is that one can solve problems of this sort very quickly if one gets to see the actual C# code that used the BC libraries. One does not need to look at the BC library sources - just how they are used to create the OP Public Key.

Before my first post on this I did a quick check on the posted Base64. It does not seem represent an RSA or DSA PublicKey or PrivateKey since I can't load it into an X509EncodedKeySpec or a PKCS8EncodedKeySpec and it is far too long (258 bytes after decoding) to be a SecretKey.

Edit: This problem interested me so I viewed the Base64 content using the asn1 viewer from http://www.obj-sys.com//av211DL/asn1vekits.php . It looks to me like the Base64 content is not an ASN.1 encoded structure. This re-enforces my view that we need to see the OP's code that he used to generate the Base64 data.
Duran Harris
Ranch Hand

Joined: Nov 09, 2008
Posts: 598

This is frustating....the code that generates the key isn't available.I can just see an interface with the methods used and some sort of reference to a .dll contained in the project...I say that the string is Base64 encoded because at some point when I was using the methods below it complained about characters that were not part of Base64 encoding scheme.Argg...

Am trying to hassle the (ex) developer to give me the source code although I suspect she no longer has it.But hey,'whose deadline is it anyway'?
Duran Harris
Ranch Hand

Joined: Nov 09, 2008
Posts: 598

Is there an alternative to the JCe Cipher class that I can use?The JVM on which the app must run doesn't seem to have it...Or should I just add it to the classpath?
Pat Farrell
Rancher

Joined: Aug 11, 2007
Posts: 4658
    
    5

Duran Harris wrote:Is there an alternative to the JCe Cipher class that I can use?The JVM on which the app must run doesn't seem to have it...Or should I just add it to the classpath?

Just add it to the classpath. Its not part of the standard distribution because some governments have restrictions on crypto. The Java maintainers want to be free to distribute the JDK and JRE, one version for the whole world. So JCE has to be an addon.

Look at all the hassle RIM has to do in the past couple of months in India, Saudi Arabia, and other countries that do not want their citizens to have access to encrypted communications.
Duran Harris
Ranch Hand

Joined: Nov 09, 2008
Posts: 598

Seems to be X509...
James Sabre
Ranch Hand

Joined: Sep 07, 2004
Posts: 781

Duran Harris wrote:This is frustating....the code that generates the key isn't available.I can just see an interface with the methods used and some sort of reference to a .dll contained in the project...

I don't think that your Base64 string represents a public key. The interface you publish seems to be nothing more than a back to front encryption that uses a (public key/ private key) pair and encrypts data.

I would be concerned about why the code that implements that interface isn't available. What is so secret about the code that stops you having access to it. Kerckhoffs' principle applies.


I say that the string is Base64 encoded because at some point when I was using the methods below it complained about characters that were not part of Base64 encoding scheme.Argg...



This interface looks unusual being back to front from that I would expect. It is normal to encrypt with the public key and decrypt with the private key OR to sign with the private key and check a signature with the public key. I can make guesses as to what the encrypt and decrypt methods actually do. Nothing very clever. I bet that the EncryptData method does nothing more than convert the 'Data' to bytes (using some unspecified but important character encoding) and then encrypt the resulting bytes using the PrivateKey (which you need to export preferably formatted as PKCS8) before encoding as base64. I would guess that PKCS1 padding is being used. The DecryptData() method will of course do the reverse and you will need to extract the public key preferably in X509 format. What the other methods do is difficult to say since I have no idea of the context.

Based on your original post I would suggest that you do significant background reading before going any further. A good starting point is "Beginning Cryptography with Java" by David Hook published by Wrox. While you are doing this reading you should petition the people who wrote the C# code to either release it to you or to define exactly what is happening behind the scenes. There can be no excuse as to why the code can't be released since if it contains proprietary algorithms you will not be able to create a Java version and if it does not contain proprietary algorithms then everything is public domain anyway.
Ulf Dittmer
Marshal

Joined: Mar 22, 2005
Posts: 41884
    
  63
Pat Farrell wrote:
Duran Harris wrote:Is there an alternative to the JCe Cipher class that I can use?The JVM on which the app must run doesn't seem to have it...Or should I just add it to the classpath?

Just add it to the classpath. Its not part of the standard distribution because some governments have restrictions on crypto. The Java maintainers want to be free to distribute the JDK and JRE, one version for the whole world. So JCE has to be an addon.

JCE has been part of the JRE since Java 1.4, so it does not need to be added. Unless you're using an even older JRE, but you mentioned Java 1.4, so you should all set.

(The BouncyCastle libraries -if you want to use those on the Java side as well- are not part of any JRE, so they always need to be added.)
Duran Harris
Ranch Hand

Joined: Nov 09, 2008
Posts: 598

Thanks for you're extensive answers...I will definitely have a look at the Java Cryptography book.I contacted the developer(who no longer has the source code) so I am going to try and use a tool to (decompile/disassemble the DLL) and hopefully be able to see the source..Apart from this, here is some code that I have been playing with to try and decrypt it that I dont know might offer some insight:



Although my code fails with a ClassNotFoundException for java.lang.StringBuilder when I try to call Cipher.init(we are using a cut-down JVM)I even tried using the oldest JCE and Bouncy Castle libraries that I could find(JDK 1.2) but this didn't alleviate the problem..I said that we use a java 1.4 VM but that's not really correct, I believe it is a Skelmir CEE-J JVM....
Duran Harris
Ranch Hand

Joined: Nov 09, 2008
Posts: 598

Yay!! I got the method disassembled using .NET Reflector!!Can you help me further now??






James Sabre
Ranch Hand

Joined: Sep 07, 2004
Posts: 781

Duran Harris wrote:Yay!! I got the method disassembled using .NET Reflector!!Can you help me further now??

Yes I can help but I won't write the code for you. It does not look to be too difficult. Not a one-one conversion but petty close. Since you failed to post most of the code for the methods any help will be very limited.
Duran Harris
Ranch Hand

Joined: Nov 09, 2008
Posts: 598

No I wouldn't expect you to write it for me...
Could you just tell me in ,my code above(the Java code), what would I need to change in order to get it to work?
James Sabre
Ranch Hand

Joined: Sep 07, 2004
Posts: 781

Duran Harris wrote:No I wouldn't expect you to write it for me...
Could you just tell me in ,my code above(the Java code), what would I need to change in order to get it to work?


You first have to fix the obvious bug in the C#! This C# code will only work if the input has length less than or equal to one block!


Since this cannot have been tested, the author of this code should be sacked!
Duran Harris
Ranch Hand

Joined: Nov 09, 2008
Posts: 598

Googling...
James Sabre
Ranch Hand

Joined: Sep 07, 2004
Posts: 781

Duran Harris wrote:No I wouldn't expect you to write it for me...
Could you just tell me in ,my code above(the Java code), what would I need to change in order to get it to work?


I can't comment on your key generation code since I don't have access to the C# code.

Since you have not written any of the actual encryption code you need to add it. For this you need to learn about the JCE (or the BC lightweight components if you are going to go down that route).
Duran Harris
Ranch Hand

Joined: Nov 09, 2008
Posts: 598

I have access to all the encryption code now....If you would like to see...
Also my colleague said that that code shouldn't be a problem because: 'why would you have more than one block'?

James Sabre
Ranch Hand

Joined: Sep 07, 2004
Posts: 781

Duran Harris wrote:I have access to all the encryption code now....If you would like to see...
Also my colleague said that that code shouldn't be a problem because: 'why would you have more than one block'?


In it's basic form, RSA can encrypt a block plaintext of up to the modulus length in bytes. When used with PKCS1 padding it can only encrypt up to the modulus length - 11 bytes. If you use a 1024 bit RSA key this means you can only encrypt up to 1024/8 - 11 = 117 bytes. The loop in that code is meant to allow the plaintext to be broken into a number of blocks presumably all smaller than the modulus length - 11 bytes. The C# code is meant to transparently handle this but the bug means that it won't. Your colleague is just trying to protect his or her backside.

When using RSA for encryption it is normal you use a hybrid approach. One uses RSA to encrypt a random symmetric key and one uses the symmetric algorithm to encrypt the plaintext. Since RSA is a very slow algorithm when compared to the symmetric algorithms such as AES this makes sense when encrypting large plaintext.

So are you going to write the Java code to duplicate the bug in the C# or are you going to fix the C# code ?
Duran Harris
Ranch Hand

Joined: Nov 09, 2008
Posts: 598

The information that I actually expected to be encrypted has only been MD5'd .The information that was encrypted with Bouncy Castle is of no use to my requirements.I did write the Java code that duplicates the bug in the C#, but I will leave it for someone who actually understands encryption to fix.Or seeing as theres nothing really useful to decrypt,I can have a look at that cryptography book at my own leisure...

Sorry for wasting so much of your time on this
James Sabre
Ranch Hand

Joined: Sep 07, 2004
Posts: 781

Duran Harris wrote:The information that I actually expected to be encrypted has only been MD5'd .

:-)

The information that was encrypted with Bouncy Castle is of no use to my requirements.I did write the Java code that duplicates the bug in the C#, but I will leave it for someone who actually understands encryption to fix.Or seeing as theres nothing really useful to decrypt,I can have a look at that cryptography book at my own leisure...

Go for it. You might find it interesting.

Sorry for wasting so much of your time on this


I would only consider it a waste of time if you had learned nothing.
 
Consider Paul's rocket mass heater.
 
subject: Help to decrypt string containing RSA public key