views:

1398

answers:

4

I've been trying to make sense of the BouncyCastle cryptography APIs for Java. Unfortunately, I'm finding Java cryptography in general to be so obscured by service provider interfaces and jargon that I can't wrap my head around what anything actually does. I've tried reading the necessary documentation repeatedly but it just stays incomprehensible, introducing many concepts far beyond what I think should be needed.

All I really want is a class that does the following:

public class KeyPair {
    public byte[] public;
    public byte[] private;
}

public class RSACrypto {
    public static KeyPair generateRSAKeyPair() { /*implementation*/}
    public static byte[] encrypt(byte[] data, byte[] publicKey) { /*impl*/}
    public static byte[] decrypt(byte[] encryptedData, byte[] privateKey) { /*impl*/ }
}

Apologies if this is an incredibly complicated question to ask as "all I really want". Any pointers on where to read up on Java cryptography and BouncyCastle are very welcome. Any overviews of how the Java crypto systems actually are laid out are extremely welcome.

+1  A: 

hmm, have you tried the O'Reilly book on Java Cryptography? (can't vouch for it personally)

Jason S
+6  A: 

No nonsense Bouncycastle RSA Example

That should give you a decent starting point.

James Van Huis
Wow. That was perfect.NOTE to reader - there's multiple pages, the page markers are in tiny little font at the bottom. I didn't notice and was wondering where the encrypt example was...
bethlakshmi
+2  A: 
import java.security.GeneralSecurityException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;

import javax.crypto.Cipher;

public class RSACrypto
{

  /* A 1024-bit key will encrypt messages up to 117 bytes long. */
  private static final int KEY_SIZE = 1024;

  private static final String XFORM = 
    "RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING";

  public static KeyPair generateRSAKeyPair()
    throws GeneralSecurityException
  {
    KeyPairGenerator gen = KeyPairGenerator.getInstance("RSA");
    gen.initialize(KEY_SIZE);
    return gen.generateKeyPair();
  }

  public static byte[] encrypt(byte[] plaintext, PublicKey pub)
    throws GeneralSecurityException
  {
    Cipher cipher = Cipher.getInstance(XFORM);
    cipher.init(Cipher.ENCRYPT_MODE, pub);
    return cipher.doFinal(plaintext);
  }

  public static byte[] decrypt(byte[] ciphertext, PrivateKey pvt)
    throws GeneralSecurityException
  {
    Cipher cipher = Cipher.getInstance(XFORM);
    cipher.init(Cipher.DECRYPT_MODE, pvt);
    return cipher.doFinal(ciphertext);
  }

  public static void main(String... argv)
    throws Exception
  {
    KeyPair pair = RSACrypto.generateRSAKeyPair();
    byte[] plaintext = "A short secret message.".getBytes("UTF-8");
    byte[] ciphertext = RSACrypto.encrypt(plaintext, pair.getPublic());
    byte[] recovered = RSACrypto.decrypt(ciphertext, pair.getPrivate());
    System.out.println(new String(recovered, "UTF-8"));
  }

}
erickson
A: 
import java.security.GeneralSecurityException;
import java.security.KeyFactory;
import java.security.KeyPairGenerator;
import java.security.PublicKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

import javax.crypto.Cipher;

public class RsaCrypto {

    private static final int KEY_SIZE = 3072;
    private static final String TRANSFORMATION = "RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING";

    public static KeyPair generateRSAKeyPair() {
        try {
            KeyPairGenerator gen = KeyPairGenerator.getInstance("RSA");
            gen.initialize(KEY_SIZE);
            java.security.KeyPair p = gen.generateKeyPair();
            KeyPair pair = new KeyPair();
            pair.privateKey = p.getPrivate().getEncoded();
            pair.publicKey = p.getPublic().getEncoded();
            return pair;
        } catch (GeneralSecurityException e) {
            throw new RuntimeException(e);
        }

    }

    public static byte[] encrypt(byte[] data, byte[] publicKey) {
        X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(publicKey);
        try {
            KeyFactory kf = KeyFactory.getInstance("RSA");
            PublicKey pk = kf.generatePublic(publicKeySpec);
            Cipher rsa = Cipher.getInstance(TRANSFORMATION);
            rsa.init(Cipher.ENCRYPT_MODE, pk);
            return rsa.doFinal(data);
        } catch (GeneralSecurityException e) {
            throw new RuntimeException(e);
        }
    }

    public static byte[] decrypt(byte[] encryptedData, byte[] privateKey) {
        try {
            PKCS8EncodedKeySpec privSpec = new PKCS8EncodedKeySpec(privateKey);
            RSAPrivateKey pk = (RSAPrivateKey) KeyFactory.getInstance("RSA")
                    .generatePrivate(privSpec);

            Cipher rsaCipher = Cipher.getInstance(TRANSFORMATION);
            rsaCipher.init(Cipher.DECRYPT_MODE, pk);
            return rsaCipher.doFinal(encryptedData);

        } catch (GeneralSecurityException e) {
            throw new RuntimeException(e);
        }
    }

}
Mark