summaryrefslogtreecommitdiff
path: root/src/org/noreply/fancydress/crypto/RSAPublicKey.java
diff options
context:
space:
mode:
authorPeter Palfrader <peter@palfrader.org>2003-10-09 11:41:45 +0000
committerPeter Palfrader <peter@palfrader.org>2003-10-09 11:41:45 +0000
commit566d17f731637df6828bdf32502a0fb123882dbe (patch)
treefc09fdfb90953134fa1d25f73367307502348a22 /src/org/noreply/fancydress/crypto/RSAPublicKey.java
parent018eea460ee32df1b70c40c2eca05f06c06daca5 (diff)
Initial import
Diffstat (limited to 'src/org/noreply/fancydress/crypto/RSAPublicKey.java')
-rw-r--r--src/org/noreply/fancydress/crypto/RSAPublicKey.java125
1 files changed, 125 insertions, 0 deletions
diff --git a/src/org/noreply/fancydress/crypto/RSAPublicKey.java b/src/org/noreply/fancydress/crypto/RSAPublicKey.java
new file mode 100644
index 0000000..13f8b53
--- /dev/null
+++ b/src/org/noreply/fancydress/crypto/RSAPublicKey.java
@@ -0,0 +1,125 @@
+package org.noreply.fancydress.crypto;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import org.bouncycastle.asn1.DEROctetString;
+import org.bouncycastle.asn1.ASN1Sequence;
+import org.bouncycastle.asn1.DERInputStream;
+import org.bouncycastle.asn1.x509.RSAPublicKeyStructure;
+import org.bouncycastle.crypto.AsymmetricBlockCipher;
+import org.bouncycastle.crypto.InvalidCipherTextException;
+import org.bouncycastle.crypto.engines.RSAEngine;
+import org.bouncycastle.crypto.digests.SHA1Digest;
+import org.bouncycastle.crypto.encodings.OAEPEncoding;
+import org.bouncycastle.crypto.params.RSAKeyParameters;
+import org.noreply.fancydress.misc.Util;
+
+/**
+ * This class is a wrapper for the bouncycastle RSA functionality.
+ */
+public class RSAPublicKey {
+ /**
+ * The overhead (in octets) added by OAEP padding.
+ */
+ public static final int PK_OVERHEAD_LEN = 42;
+ /**
+ * The length of encrypted data. (we use 2048 bit keys)
+ */
+ public static final int PK_ENC_LEN = 256;
+ /**
+ * The maximum amount of octets that can be encoded in an RSA message.
+ */
+ public static final int PK_MAX_DATA_LEN = PK_ENC_LEN - PK_OVERHEAD_LEN;
+
+ /**
+ * the RSA cipher from bouncycastle.
+ */
+ private AsymmetricBlockCipher rsa_cipher;
+ /**
+ * a key structure
+ */
+ private RSAPublicKeyStructure key;
+ /**
+ * key parameters
+ */
+ private RSAKeyParameters keyParams;
+
+ /**
+ * Construct an instance of an RSAPublicKey from the ASN1 encoded key.
+ *
+ * @param asnEncoded ASN1 encoded RSA key.
+ */
+ public RSAPublicKey(byte[] asnEncoded) {
+ String p = new String("He who would make his own liberty secure, must guard even his enemy from oppression.");
+ rsa_cipher = new OAEPEncoding(new RSAEngine(), new SHA1Digest(), CryptoPrimitives.hash(Util.toOctets(p)));
+
+ ByteArrayInputStream bIn = new ByteArrayInputStream(asnEncoded);
+ DERInputStream dIn = new DERInputStream(bIn);
+ try {
+ key = new RSAPublicKeyStructure((ASN1Sequence)dIn.readObject());
+ } catch (IOException e) {
+ throw new Error(e);
+ }
+ keyParams = new RSAKeyParameters(false, key.getModulus(), key.getPublicExponent());
+ };
+ /**
+ * Encrypt a message.
+ *
+ * Encrypts message m to this key.
+ *
+ * @param m the message to encrypt.
+ * @return the encrypted message (PK_ENC_LEN octets long)
+ */
+ public byte[] encrypt(byte[] m) {
+ rsa_cipher.init(true, keyParams);
+ byte[] result;
+ try {
+ result = rsa_cipher.processBlock(m, 0, m.length);
+ } catch (InvalidCipherTextException e) {
+ throw new Error(e);
+ }
+ return(result);
+ }
+ /**
+ * Verify a signature.
+ *
+ * Verify that the information signed in signature <code>sig</code>
+ * matches the value in <code>m</code>.
+ *
+ * @param sig the signature
+ * @param m message to compare the signed information to
+ * @return true if the signature is valid
+ * @throws InvalidCipherTextException
+ */
+ public boolean verify(byte[] sig, byte[] m) throws InvalidCipherTextException {
+ rsa_cipher.init(false, keyParams);
+ byte[] signedDigest = rsa_cipher.processBlock(sig, 0, sig.length);
+ byte[] digest = CryptoPrimitives.hash(m);
+ boolean verifies = Util.equal(digest, signedDigest);
+ return(verifies);
+ }
+ /**
+ * Return the ASN 1 encoding of this key.
+ *
+ * @return this key, asn1 encoded
+ */
+ public byte[] encode() {
+ DEROctetString asn = new DEROctetString(key);
+ byte[] result = asn.getOctets();
+ return(result);
+ }
+ /**
+ * Get this key's fingerprint.
+ *
+ * The fingerprint (or keyid) is the hash of the asn1 representation of this key.
+ *
+ * @return the fingerprint.
+ */
+ public byte[] getFingerprint() {
+ DEROctetString asn = new DEROctetString(key);
+ byte[] encoded = asn.getOctets();
+ byte[] result = CryptoPrimitives.hash(encoded);
+ return(result);
+ }
+}