173 lines
5.3 KiB
Java
173 lines
5.3 KiB
Java
/**
|
|
* Author: Timothy Prepscius
|
|
* License: GPLv3 Affero + keep my name in the code!
|
|
*/
|
|
|
|
package core.crypt;
|
|
|
|
import java.io.ByteArrayInputStream;
|
|
import java.io.IOException;
|
|
import java.security.SecureRandom;
|
|
|
|
import org.bc.asn1.ASN1InputStream;
|
|
import org.bc.asn1.ASN1Integer;
|
|
import org.bc.asn1.ASN1ObjectIdentifier;
|
|
import org.bc.asn1.ASN1OctetString;
|
|
import org.bc.asn1.ASN1Primitive;
|
|
import org.bc.asn1.ASN1Sequence;
|
|
import org.bc.asn1.DERBitString;
|
|
import org.bc.asn1.pkcs.RSAPrivateKey;
|
|
import org.bc.asn1.pkcs.RSAPublicKey;
|
|
import org.bc.crypto.encodings.PKCS1Encoding;
|
|
import org.bc.crypto.engines.RSAEngine;
|
|
import org.bc.crypto.params.RSAKeyParameters;
|
|
|
|
import core.exceptions.CryptoException;
|
|
import core.util.Arrays;
|
|
|
|
|
|
public class CryptorRSABC extends CryptorRSA
|
|
{
|
|
SecureRandom random = new SecureRandom();
|
|
|
|
public final int MAX_RSA_BLOCK_SIZE = 117;
|
|
|
|
RSAPublicKey publicKey;
|
|
RSAPrivateKey privateKey;
|
|
|
|
public static final byte[] iv = Arrays.generate(16, 0);
|
|
|
|
public CryptorRSABC (byte[] publicKey, byte[] privateKey) throws CryptoException
|
|
{
|
|
initialize(publicKey, privateKey);
|
|
|
|
try
|
|
{
|
|
if (privateKey != null)
|
|
{
|
|
ASN1InputStream asn1InputStream = new ASN1InputStream(new ByteArrayInputStream(privateKey));
|
|
ASN1Primitive keyObject = asn1InputStream.readObject();
|
|
asn1InputStream.close();
|
|
|
|
ASN1Sequence keySequence = (ASN1Sequence)keyObject;
|
|
ASN1Integer pkcs8Version = (ASN1Integer) keySequence.getObjectAt(0);
|
|
ASN1Sequence algorithmSequence = (ASN1Sequence) keySequence.getObjectAt(1);
|
|
ASN1ObjectIdentifier algorithmIdentifier = (ASN1ObjectIdentifier) algorithmSequence.getObjectAt(0);
|
|
|
|
String algorithm = algorithmIdentifier.getId();
|
|
if (!algorithm.equals("1.2.840.113549.1.1.1"))
|
|
throw new CryptoException("Unknown RSA algorithm");
|
|
|
|
ASN1OctetString privateKeyOctets = (ASN1OctetString) keySequence.getObjectAt(2);
|
|
|
|
ASN1InputStream asn1PrivateKeyStream = new ASN1InputStream(privateKeyOctets.getOctetStream());
|
|
ASN1Primitive privateKeyObject = asn1PrivateKeyStream.readObject();
|
|
asn1PrivateKeyStream.close();
|
|
ASN1Sequence privateKeySequence = (ASN1Sequence)privateKeyObject;
|
|
|
|
int I=0;
|
|
ASN1Integer
|
|
s = (ASN1Integer)privateKeySequence.getObjectAt(I++),
|
|
n = (ASN1Integer)privateKeySequence.getObjectAt(I++),
|
|
e = (ASN1Integer)privateKeySequence.getObjectAt(I++),
|
|
d = (ASN1Integer)privateKeySequence.getObjectAt(I++),
|
|
p = (ASN1Integer)privateKeySequence.getObjectAt(I++),
|
|
q = (ASN1Integer)privateKeySequence.getObjectAt(I++),
|
|
d1 = (ASN1Integer)privateKeySequence.getObjectAt(I++),
|
|
d2 = (ASN1Integer)privateKeySequence.getObjectAt(I++),
|
|
c = (ASN1Integer)privateKeySequence.getObjectAt(I++)
|
|
;
|
|
|
|
/*
|
|
org.bouncycastle.asn1.pkcs.RSAPrivateKey.RSAPrivateKey(
|
|
BigInteger modulus,
|
|
BigInteger publicExponent,
|
|
BigInteger privateExponent,
|
|
BigInteger prime1,
|
|
BigInteger prime2,
|
|
BigInteger exponent1,
|
|
BigInteger exponent2,
|
|
BigInteger coefficient
|
|
)
|
|
*/
|
|
this.privateKey =
|
|
new RSAPrivateKey(
|
|
n.getValue(),
|
|
e.getValue(),
|
|
d.getValue(),
|
|
p.getValue(),
|
|
q.getValue(),
|
|
d1.getValue(),
|
|
d2.getValue(),
|
|
c.getValue()
|
|
);
|
|
}
|
|
|
|
if (publicKey != null)
|
|
{
|
|
ASN1InputStream asn1InputStream = new ASN1InputStream(new ByteArrayInputStream(publicKey));
|
|
ASN1Primitive keyObject = asn1InputStream.readObject();
|
|
asn1InputStream.close();
|
|
|
|
ASN1Sequence keySequence = (ASN1Sequence)keyObject;
|
|
ASN1Sequence algorithmSequence = (ASN1Sequence) keySequence.getObjectAt(0);
|
|
ASN1ObjectIdentifier algorithmIdentifier = (ASN1ObjectIdentifier) algorithmSequence.getObjectAt(0);
|
|
|
|
String algorithm = algorithmIdentifier.getId();
|
|
if (!algorithm.equals("1.2.840.113549.1.1.1"))
|
|
throw new CryptoException("Unknown RSA algorithm");
|
|
|
|
DERBitString keyOctets = (DERBitString) keySequence.getObjectAt(1);
|
|
ASN1InputStream asn1PublicKeyStream = new ASN1InputStream(new ByteArrayInputStream(keyOctets.getBytes()));
|
|
ASN1Primitive publicKeyObject = asn1PublicKeyStream.readObject();
|
|
asn1PublicKeyStream.close();
|
|
|
|
ASN1Sequence publicKeySequence = (ASN1Sequence)publicKeyObject;
|
|
|
|
int I=0;
|
|
ASN1Integer
|
|
n = (ASN1Integer)publicKeySequence.getObjectAt(I++),
|
|
e = (ASN1Integer)publicKeySequence.getObjectAt(I++);
|
|
|
|
this.publicKey = new RSAPublicKey(n.getValue(), e.getValue());
|
|
}
|
|
}
|
|
catch (IOException e)
|
|
{
|
|
throw new CryptoException(e);
|
|
}
|
|
}
|
|
|
|
public byte[] encrypt (byte[] block) throws CryptoException
|
|
{
|
|
try
|
|
{
|
|
PKCS1Encoding e = new PKCS1Encoding(new RSAEngine());
|
|
RSAKeyParameters key = new RSAKeyParameters(false, publicKey.getModulus(), publicKey.getPublicExponent());
|
|
e.init(true, key);
|
|
|
|
return e.processBlock(block, 0, block.length);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
throw new CryptoException(e);
|
|
}
|
|
}
|
|
|
|
public byte[] decrypt (byte[] block) throws CryptoException
|
|
{
|
|
try
|
|
{
|
|
PKCS1Encoding e = new PKCS1Encoding(new RSAEngine());
|
|
RSAKeyParameters key = new RSAKeyParameters(false, privateKey.getModulus(), privateKey.getPrivateExponent());
|
|
e.init(false, key);
|
|
|
|
return e.processBlock(block, 0, block.length);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
throw new CryptoException(e);
|
|
}
|
|
}
|
|
}
|