java - Correct way to sign and verify signature using bouncycastle -
i using bcmail-jdk16-1.46.jar
, bcprov-jdk16-1.46.jar
(bouncycastle libraries) sign string
, verify signature
.
this code
sign string
:
package my.package; 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.list; import org.bouncycastle.cert.jcajce.jcacertstore; import org.bouncycastle.cms.cmsprocessablebytearray; import org.bouncycastle.cms.cmssigneddata; import org.bouncycastle.cms.cmssigneddatagenerator; import org.bouncycastle.cms.cmstypeddata; import org.bouncycastle.cms.jcajce.jcasignerinfogeneratorbuilder; 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; import sun.misc.base64encoder; public class signmessage { 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"; public static void main(string[] args) throws exception { string text = "this message"; security.addprovider(new bouncycastleprovider()); keystore ks = keystore.getinstance(keystore_instance); ks.load(new fileinputstream(keystore_file), keystore_pwd.tochararray()); key key = ks.getkey(keystore_alias, keystore_pwd.tochararray()); //sign privatekey privkey = (privatekey) key; signature signature = signature.getinstance("sha1withrsa", "bc"); signature.initsign(privkey); signature.update(text.getbytes()); //build cms x509certificate cert = (x509certificate) ks.getcertificate(keystore_alias); list certlist = new arraylist(); cmstypeddata msg = new cmsprocessablebytearray(signature.sign()); certlist.add(cert); store certs = new jcacertstore(certlist); cmssigneddatagenerator gen = new cmssigneddatagenerator(); contentsigner sha1signer = new jcacontentsignerbuilder("sha1withrsa").setprovider("bc").build(privkey); gen.addsignerinfogenerator(new jcasignerinfogeneratorbuilder(new jcadigestcalculatorproviderbuilder().setprovider("bc").build()).build(sha1signer, cert)); gen.addcertificates(certs); cmssigneddata sigdata = gen.generate(msg, false); base64encoder encoder = new base64encoder(); string signedcontent = encoder.encode((byte[]) sigdata.getsignedcontent().getcontent()); system.out.println("signed content: " + signedcontent + "\n"); string envelopeddata = encoder.encode(sigdata.getencoded()); system.out.println("enveloped data: " + envelopeddata); } }
now, envelopeddata
output used in process verify
signature
way:
package my.package; import java.security.security; import java.security.cert.x509certificate; import java.util.collection; import java.util.iterator; import org.bouncycastle.cert.x509certificateholder; import org.bouncycastle.cert.jcajce.jcax509certificateconverter; import org.bouncycastle.cms.cmssigneddata; import org.bouncycastle.cms.signerinformation; import org.bouncycastle.cms.signerinformationstore; import org.bouncycastle.cms.jcajce.jcasimplesignerinfoverifierbuilder; import org.bouncycastle.jce.provider.bouncycastleprovider; import org.bouncycastle.util.store; import org.bouncycastle.util.encoders.base64; public class verifysignature { public static void main(string[] args) throws exception { string envelopeddata = "miagcsqgsib3dqehaqcamiacaqexczajbgurdgmcgguamiagcsqgsib3dqehaqaaoiawgglqmiic" + "oqieq479uzanbgkqhkig9w0baqufadcbrjemmcqgcsqgsib3dqejaryxcm9zzxr0yw5ldebtzw5k" + "zwxzb24uzguxczajbgnvbaytakrfmq8wdqydvqqiewzczxjsaw4xdzanbgnvbactbkjlcmxpbjei" + "mcaga1uechmzbwvuzgvsc29ulwuty29tbwvyy2ugr21isdeimcaga1uecxmzbwvuzgvsc29ulwut" + "y29tbwvyy2ugr21isdenmasga1ueaxmebwvuzdaefw0wnteymdexmzqymtlafw0xota4mtaxmzqy" + "mtlamigumsywjayjkozihvcnaqkbfhdyb3nldhrhbmv0qg1lbmrlbhnvbi5kztelmakga1uebhmc" + "reuxdzanbgnvbagtbkjlcmxpbjepma0ga1uebxmgqmvybglumsiwiaydvqqkexltzw5kzwxzb24t" + "zs1jb21tzxjjzsbhbwjimsiwiaydvqqlexltzw5kzwxzb24tzs1jb21tzxjjzsbhbwjimq0wcwyd" + "vqqdewrtzw5kmigfma0gcsqgsib3dqebaquaa4gnadcbiqkbgqc+x1g6jvbdwji6mqmnt41gcych" + "ubwcfwkj4qhdahffz3n4h+uqjjoqvc8yltcfnl109gb0yl2y5yqttohos9iwyymwbhh77wjtcn8r" + "dofd2dw17877te+nlpugrvg6eoh6np9vn3rzodvxxtyyj8pi8vmnn13yeymmw7vvaeo5hqidaqab" + "ma0gcsqgsib3dqebbquaa4gbalwoic/rwmaandeh/ggo/dskvmwxm5ubr3tkyblu/5jg0lwj3y++" + "khumysrxnyewslqk+jxa4os9nj+b3ezrznnyq9ekeuzgde/qp9xe04y8wl6zhlb4sdnmsgvatu+p" + "0lfyh0te9nypbg0j88109cxkdxctsn5gq0s1cfyn0staaaaxggg9miibuqibatcbtzcbrjemmcqg" + "csqgsib3dqejaryxcm9zzxr0yw5ldebtzw5kzwxzb24uzguxczajbgnvbaytakrfmq8wdqydvqqi" + "ewzczxjsaw4xdzanbgnvbactbkjlcmxpbjeimcaga1uechmzbwvuzgvsc29ulwuty29tbwvyy2ug" + "r21isdeimcaga1uecxmzbwvuzgvsc29ulwuty29tbwvyy2ugr21isdenmasga1ueaxmebwvuzaie" + "q479uzajbgurdgmcgguaof0wgayjkozihvcnaqkdmqsgcsqgsib3dqehatacbgkqhkig9w0bcqux" + "dxcnmtmwntixmde1mduzwjajbgkqhkig9w0bcqqxfgqu8me6gw6iudxluc9379lwk0luswcwdqyj" + "kozihvcnaqebbqaegyb5mvhqju1ix9nuqfqk7htyjb1lr/hqicaxrueuinkuvtglyuyzivzjar54" + "zx7cfm5lkcryyxq35ztqoq/v5jzba+dykiskchgptjx3cbmmdia1s65meye4els4mtbvxcncutb9" + "styswvr4vpenn80mbpqss6jpvxjm0gf3qtahhwaaaaaaaa=="; security.addprovider(new bouncycastleprovider()); cmssigneddata cms = new cmssigneddata(base64.decode(envelopeddata.getbytes())); store store = cms.getcertificates(); signerinformationstore signers = cms.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 cert = new jcax509certificateconverter().setprovider("bc").getcertificate(certholder); if (signer.verify(new jcasimplesignerinfoverifierbuilder().setprovider("bc").build(cert))) { system.out.println("verified"); } } } }
everything works until signer.verify(..)
due following exception
:
exception in thread "main" org.bouncycastle.cms.cmssignerdigestmismatchexception: message-digest attribute value not match calculated value @ org.bouncycastle.cms.signerinformation.doverify(unknown source) @ org.bouncycastle.cms.signerinformation.verify(unknown source) @ my.package.verifysignature.main(verifysignature.java:64)
and don't know doing wrong. can please give me hint of happening?
ps. if wants test above code
, need test certificate
file using replicate this, download/save
here:
https://dl.dropboxusercontent.com/u/15208254/keys/certificates.p12
the
gen.generate(msg, false)
means signed data not encapsulated in signature. fine if want create detached signature, mean when go verify signeddata have use cmssigneddata constructor takes copy of data - in case code using single argument constructor has assume signed data encapsulated (so case empty), result attempt @ verification failing.
Comments
Post a Comment