org.testifyproject.bouncycastle.crypto.signers.DSADigestSigner Maven / Gradle / Ivy
The newest version!
package org.testifyproject.bouncycastle.crypto.signers;
import java.io.IOException;
import java.math.BigInteger;
import org.testifyproject.bouncycastle.asn1.ASN1EncodableVector;
import org.testifyproject.bouncycastle.asn1.ASN1Encoding;
import org.testifyproject.bouncycastle.asn1.ASN1Integer;
import org.testifyproject.bouncycastle.asn1.ASN1Primitive;
import org.testifyproject.bouncycastle.asn1.ASN1Sequence;
import org.testifyproject.bouncycastle.asn1.DERSequence;
import org.testifyproject.bouncycastle.crypto.CipherParameters;
import org.testifyproject.bouncycastle.crypto.DSA;
import org.testifyproject.bouncycastle.crypto.Digest;
import org.testifyproject.bouncycastle.crypto.Signer;
import org.testifyproject.bouncycastle.crypto.params.AsymmetricKeyParameter;
import org.testifyproject.bouncycastle.crypto.params.ParametersWithRandom;
public class DSADigestSigner
implements Signer
{
private final Digest digest;
private final DSA dsaSigner;
private boolean forSigning;
public DSADigestSigner(
DSA signer,
Digest digest)
{
this.digest = digest;
this.dsaSigner = signer;
}
public void init(
boolean forSigning,
CipherParameters parameters)
{
this.forSigning = forSigning;
AsymmetricKeyParameter k;
if (parameters instanceof ParametersWithRandom)
{
k = (AsymmetricKeyParameter)((ParametersWithRandom)parameters).getParameters();
}
else
{
k = (AsymmetricKeyParameter)parameters;
}
if (forSigning && !k.isPrivate())
{
throw new IllegalArgumentException("Signing Requires Private Key.");
}
if (!forSigning && k.isPrivate())
{
throw new IllegalArgumentException("Verification Requires Public Key.");
}
reset();
dsaSigner.init(forSigning, parameters);
}
/**
* update the internal digest with the byte b
*/
public void update(
byte input)
{
digest.update(input);
}
/**
* update the internal digest with the byte array in
*/
public void update(
byte[] input,
int inOff,
int length)
{
digest.update(input, inOff, length);
}
/**
* Generate a signature for the message we've been loaded with using
* the key we were initialised with.
*/
public byte[] generateSignature()
{
if (!forSigning)
{
throw new IllegalStateException("DSADigestSigner not initialised for signature generation.");
}
byte[] hash = new byte[digest.getDigestSize()];
digest.doFinal(hash, 0);
BigInteger[] sig = dsaSigner.generateSignature(hash);
try
{
return derEncode(sig[0], sig[1]);
}
catch (IOException e)
{
throw new IllegalStateException("unable to encode signature");
}
}
public boolean verifySignature(
byte[] signature)
{
if (forSigning)
{
throw new IllegalStateException("DSADigestSigner not initialised for verification");
}
byte[] hash = new byte[digest.getDigestSize()];
digest.doFinal(hash, 0);
try
{
BigInteger[] sig = derDecode(signature);
return dsaSigner.verifySignature(hash, sig[0], sig[1]);
}
catch (IOException e)
{
return false;
}
}
public void reset()
{
digest.reset();
}
private byte[] derEncode(
BigInteger r,
BigInteger s)
throws IOException
{
ASN1EncodableVector v = new ASN1EncodableVector();
v.add(new ASN1Integer(r));
v.add(new ASN1Integer(s));
return new DERSequence(v).getEncoded(ASN1Encoding.DER);
}
private BigInteger[] derDecode(
byte[] encoding)
throws IOException
{
ASN1Sequence s = (ASN1Sequence)ASN1Primitive.fromByteArray(encoding);
return new BigInteger[]
{
((ASN1Integer)s.getObjectAt(0)).getValue(),
((ASN1Integer)s.getObjectAt(1)).getValue()
};
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy