java - Verify a signature with bouncy castle -
i inherited code using deprecated bouncycastle api. before updating new api wanted write test verify didn't change behaviour. however, cannot work out correct way verify signature generated. code changed is:
public static byte[] createsigneddata(byte[] content, x509certificate cert, privatekey key) throws nosuchalgorithmexception, nosuchproviderexception, cmsexception, ioexception { // set generator cmssigneddatagenerator gen = new cmssigneddatagenerator(); gen.addsigner(key, cert, cmssignedgenerator.digest_sha1); // create signed-data object cmsprocessable data = new cmsprocessablebytearray(content); cmssigneddata signed = gen.generate(data, bc_provider); return signed.getencoded(); }
what being returned code? detached signature? tried verify signature small piece of code this, returns false:
signature signer = signature.getinstance( "sha1withrsa", bouncycastleprovider.provider_name); signer.initverify(cert.getpublickey()); signer.update(data); return signer.verify(sig);
it return detached signature if use:
gen.generate(data, false);
otherwise return signed data encapsulated in signature. so, if signature detached (which not case) in order verify need create new cmssigneddata
object signed data bytes or base64
enconded string
, copy of original data in constructor.
i think you're not verifying signature right way, don't know bouncycastle
library version using , provided code snippet vague analyze.
this did in order sign , verify signature using bcmail-jdk16-1.46.jar
, bcprov-jdk16-1.46.jar
, jdk1.6.0_45
(i'm assuming using java since never specified it, in question tags - .net version similar).
you can download keystore used in example at: https://dl.dropboxusercontent.com/u/15208254/keys/certificates.p12
also, if want check if signature verification working fine, can change certificate (since i'm verifying against own certificate doesn't make sense) changing line in signature verification process, line 84:
if (signer.verify(new jcasimplesignerinfoverifierbuilder().setprovider(bc_provider).build(certfromsigneddata))) { ... }
and loading keystore certificate it. know, certificates.p12 file using, contains 2 certificates alias key1
, key2
can play around them signing content key1
, verifying signature key2
example.
e.g:
// load 'key2' certificate 'certificates.p12' @ place on class after 'ks' declaration x509certificate certfromkeystore2 = (x509certificate) ks.getcertificate("key2");
then replace line 84 this:
if (signer.verify(new jcasimplesignerinfoverifierbuilder().setprovider(bc_provider).build(certfromkeystore2))) { ... }
notice certfromsigneddata
changed certfromkeystore2
, signature verification fail because content signed key1
.
java code:
don't forget change keystore path in constants!
package com.example.main; import java.io.fileinputstream; import java.security.key; import java.security.keystore; import java.security.privatekey; import java.security.security; import java.security.signature; import java.security.cert.x509certificate; import java.util.arraylist; import java.util.collection; import java.util.iterator; import java.util.list; import org.bouncycastle.cert.x509certificateholder; import org.bouncycastle.cert.jcajce.jcacertstore; import org.bouncycastle.cert.jcajce.jcax509certificateconverter; import org.bouncycastle.cms.cmsprocessablebytearray; import org.bouncycastle.cms.cmssigneddata; import org.bouncycastle.cms.cmssigneddatagenerator; import org.bouncycastle.cms.cmstypeddata; import org.bouncycastle.cms.signerinformation; import org.bouncycastle.cms.signerinformationstore; import org.bouncycastle.cms.jcajce.jcasignerinfogeneratorbuilder; import org.bouncycastle.cms.jcajce.jcasimplesignerinfoverifierbuilder; import org.bouncycastle.jce.provider.bouncycastleprovider; import org.bouncycastle.operator.contentsigner; import org.bouncycastle.operator.jcajce.jcacontentsignerbuilder; import org.bouncycastle.operator.jcajce.jcadigestcalculatorproviderbuilder; import org.bouncycastle.util.store; public class verifysignature { static final string keystore_file = "keys/certificates.p12"; static final string keystore_instance = "pkcs12"; static final string keystore_pwd = "test"; static final string keystore_alias = "key1"; static final string digest_sha1 = "sha1withrsa"; static final string bc_provider = "bc"; @suppresswarnings({ "rawtypes", "unchecked" }) public static void main(string[] args) throws exception { // content signed string text = "my name oscar"; security.addprovider(new bouncycastleprovider()); // keystore keystore ks = keystore.getinstance(keystore_instance); ks.load(new fileinputstream(keystore_file), keystore_pwd.tochararray()); key key = ks.getkey(keystore_alias, keystore_pwd.tochararray()); // private key , sign privatekey privkey = (privatekey) key; signature signature = signature.getinstance(digest_sha1, bc_provider); signature.initsign(privkey); signature.update(text.getbytes()); // build cms x509certificate certfromkeystore = (x509certificate) ks.getcertificate(keystore_alias); list certlist = new arraylist(); cmstypeddata data = new cmsprocessablebytearray(signature.sign()); certlist.add(certfromkeystore); store certs = new jcacertstore(certlist); cmssigneddatagenerator gen = new cmssigneddatagenerator(); contentsigner sha1signer = new jcacontentsignerbuilder(digest_sha1).setprovider(bc_provider).build(privkey); gen.addsignerinfogenerator(new jcasignerinfogeneratorbuilder(new jcadigestcalculatorproviderbuilder().setprovider(bc_provider).build()).build(sha1signer, certfromkeystore)); gen.addcertificates(certs); cmssigneddata signeddata = gen.generate(data, true); // verify signature store store = signeddata.getcertificates(); signerinformationstore signers = signeddata.getsignerinfos(); collection c = signers.getsigners(); iterator = c.iterator(); while (it.hasnext()) { signerinformation signer = (signerinformation) it.next(); collection certcollection = store.getmatches(signer.getsid()); iterator certit = certcollection.iterator(); x509certificateholder certholder = (x509certificateholder) certit.next(); x509certificate certfromsigneddata = new jcax509certificateconverter().setprovider(bc_provider).getcertificate(certholder); if (signer.verify(new jcasimplesignerinfoverifierbuilder().setprovider(bc_provider).build(certfromsigneddata))) { system.out.println("signature verified"); } else { system.out.println("signature verification failed"); } } } }
Comments
Post a Comment