problem decrypting a string

hi,

I've a problem with cryptography: I'm trying to encrypt a string, put it in another string containing XML tags, send this XML by AJAX to a Servlet, and then decrypt the string.

I can't send a byte char using AJAX, so I have to convert the result of the encryption with the .toString() method.

When the string arrives to the Servlet, I reconvert it using .getBytes() method and I try to decrypt it, but i get this exception:

javax.crypto.BadPaddingException: Data must start with zero

[521 byte] By [valerio_arnaboldia] at [2007-11-27 4:52:06]
# 1

> ... so I have to convert the result of the encryption with the .toString() ...

That won't work. You find numerous examples of this mistake in this forum. You must use an encoding method such as base64 encoding to convert the result of encryption to a string. You can search these archives for base64 to find examples and discussion.

ghstarka at 2007-7-12 10:06:00 > top of Java-index,Security,Cryptography...
# 2

Ok, now I'm using a base64 encoder and decoder, but I still have a problem: when I put my encoded string between XML tags and then I retrieve it using simple string functions I get into this Exception:

javax.crypto.IllegalBlockSizeException: Data must not be longer than 128 bytes

Here is the code of a test JSP page I've used and the project Beans.

********************************************************************************

JSP page

<%@page contentType="text/html"%>

<%@page pageEncoding="UTF-8"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"

"http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>

<%@ page

import = "java.io.*"

import = "java.lang.*"

import = "javax.crypto.*"

import = "java.security.*"

%>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<jsp:useBean class="ph_prime_pkj.CryptoBean" id="CB"/>

<jsp:useBean class="ph_prime_pkj.KeyHolder" id="KH"/>

<jsp:useBean class="ph_prime_pkj.XMLReader" id="XMLR"/>

<title>KeyGen</title>

</head>

<body>

<h1>Public and Private Keys</h1>

<%

Key privateKey = KH.getPrivateKey("1","120984".toCharArray());

Key publicKey = KH.getPublicKey("1","120984".toCharArray());

out.println("Private and Public keys for farmacia1");

out.println();

out.println("Private: "+privateKey.toString());

out.println();

out.println("Public: "+publicKey.toString());

byte[] enc = CB.encrypt(publicKey,"ciao");

String stringa64 = new sun.misc.BASE64Encoder().encode(enc);

String encoded = "<data>"+stringa64+"</data>";

String encoded2 = XMLR.ReturnAttr(encoded,"data");

byte[] encodedInByte = new sun.misc.BASE64Decoder().decodeBuffer(encoded);

String outString = CB.decrypt(privateKey,encodedInByte);

%>

<%

out.print(outString);

%>

</body>

</html>

******************************************************************************

Crypto Bean

/*

* CryptoBean.java

*

* Created on 19 maggio 2007, 13.58

*/

package ph_prime_pkj;

import java.beans.*;

import java.io.Serializable;

import java.security.Key;

import javax.crypto.*;

import javax.crypto.spec.SecretKeySpec;

/**

* @author Luca Bolzoni

*/

public class CryptoBean extends Object implements Serializable {

public CryptoBean() {

}

public static byte[] encrypt(Key key, String text) throws Exception {

Cipher cipher = Cipher.getInstance("RSA");

cipher.init(javax.crypto.Cipher.ENCRYPT_MODE, key);

byte[] encrypted = cipher.doFinal(text.getBytes());

return encrypted;

}

public static String decrypt(Key key, byte[] encrypted) throws Exception {

Cipher cipher = Cipher.getInstance("RSA");

cipher.init(javax.crypto.Cipher.DECRYPT_MODE, key);

byte[] decrypted = cipher.doFinal(encrypted);

return new String(decrypted);

}

}

*****************************************************************************

keyHolder bean

/*

* KeyHolder.java

*

* Created on 18 maggio 2007, 11.46

*/

package ph_prime_pkj;

import java.beans.*;

import java.io.File;

import java.io.FileInputStream;

import java.io.FileNotFoundException;

import java.io.IOException;

import java.io.Serializable;

import java.security.Key;

import java.security.KeyPair;

import java.security.KeyStore;

import java.security.KeyStoreException;

import java.security.NoSuchAlgorithmException;

import java.security.PrivateKey;

import java.security.PublicKey;

import java.security.UnrecoverableKeyException;

import java.util.Enumeration;

/**

* @author Luca Bolzoni

*/

public class KeyHolder extends Object implements Serializable {

KeyStore keystore = null;

public KeyHolder() {

}

public PrivateKey getPrivateKey(String alias, char[] password) {

try {

File file = new File(System.getProperty("user.home") + File.separatorChar + ".keystore");

FileInputStream is = new FileInputStream(file);

keystore = KeyStore.getInstance(KeyStore.getDefaultType());

String pass = "mangusta";

keystore.load(is, pass.toCharArray());

is.close();

} catch (java.security.cert.CertificateException e) {

} catch (NoSuchAlgorithmException e) {

} catch (FileNotFoundException e) {

// Keystore does not exist

} catch (KeyStoreException e) {

} catch (IOException e) {

}

try {

// Get private key

Key key = keystore.getKey(alias, password);

if (key instanceof PrivateKey) {

// Get certificate of public key

java.security.cert.Certificate cert = keystore.getCertificate(alias);

// Get public key

PublicKey publicKey = cert.getPublicKey();

// Return a key pair

return (PrivateKey)key;

}

} catch (UnrecoverableKeyException e) {

} catch (NoSuchAlgorithmException e) {

} catch (KeyStoreException e) {

}

return null;

}

public PublicKey getPublicKey(String alias, char[] password) {

try {

File file = new File(System.getProperty("user.home") + File.separatorChar + ".keystore");

FileInputStream is = new FileInputStream(file);

keystore = KeyStore.getInstance(KeyStore.getDefaultType());

String pass = "mangusta";

keystore.load(is, pass.toCharArray());

is.close();

} catch (java.security.cert.CertificateException e) {

} catch (NoSuchAlgorithmException e) {

} catch (FileNotFoundException e) {

// Keystore does not exist

} catch (KeyStoreException e) {

} catch (IOException e) {

}

try {

// Get private key

Key key = keystore.getKey(alias, password);

if (key instanceof PrivateKey) {

// Get certificate of public key

java.security.cert.Certificate cert = keystore.getCertificate(alias);

// Get public key

PublicKey publicKey = cert.getPublicKey();

// Return a key pair

return publicKey;

}

} catch (UnrecoverableKeyException e) {

} catch (NoSuchAlgorithmException e) {

} catch (KeyStoreException e) {

}

return null;

}

}

*********************************************************************************

XMLReader Bean

/*

* XMLReader.java

*

* Created on 1 maggio 2007, 10.06

*/

package ph_prime_pkj;

import java.beans.*;

import java.io.Serializable;

import java.io.File;

import java.io.StringReader;

import org.w3c.dom.Document;

import org.w3c.dom.*;

import javax.xml.parsers.DocumentBuilderFactory;

import javax.xml.parsers.DocumentBuilder;

import org.xml.sax.InputSource;

import org.xml.sax.SAXException;

import org.xml.sax.SAXParseException;

/**

* @author Valerio

*/

public class XMLReader extends Object implements Serializable {

public String ReturnAttr(String xml, String attr){

String temp="";

int begin = xml.indexOf("<"+attr+">") + attr.length() + 2;

int end = xml.indexOf("</"+attr+">");

temp = (String) xml.subSequence(begin, end);

return temp;

}

}

Thanks a lot.

valerio_arnaboldia at 2007-7-12 10:06:00 > top of Java-index,Security,Cryptography...
# 3

The problem is that you are attempting to encrypt a String that is longer than 128 bytes with an RSA asymmetric key-pair.While RSA keys are used for encryption, they cannot be used for encrypting large objects; the size of the object that can be encrypted is very limited and depends on the RSA key size.

The typical approach is to use a symmetric encryption key - such as 3DES or AES - to encrypt your data (whatever size it may be) and then encrypt the symmetric key with an RSA public-key. The encrypted key is now (securely) transported with the encrypted data to the recipient, who decrypts the symmetric key with a corresponding RSA private key, and then uses the symmetric key to decrypt the user-data.

There are many examples of this model on this forum, in books such as David Hook's "Beginning Cryptography in Java" and in open-source software products such as StrongKey. I would encourage you to study them to understand the mechanics.

arshad.noora at 2007-7-12 10:06:00 > top of Java-index,Security,Cryptography...