Wrox Programmer Forums
Go Back   Wrox Programmer Forums > Java > Other Java > BOOK: Beginning Cryptography with Java
| Search | Today's Posts | Mark Forums Read
BOOK: Beginning Cryptography with Java
This is the forum to discuss the Wrox book Beginning Cryptography with Java by David Hook; ISBN: 9780764596339
Welcome to the p2p.wrox.com Forums.

You are currently viewing the BOOK: Beginning Cryptography with Java section of the Wrox Programmer to Programmer discussions. This is a community of software programmers and website developers including Wrox book authors and readers. New member registration was closed in 2019. New posts were shut off and the site was archived into this static format as of October 1, 2020. If you require technical support for a Wrox book please contact http://hub.wiley.com
 
Old September 15th, 2009, 09:51 AM
Registered User
 
Join Date: Aug 2007
Location: , , .
Posts: 6
Thanks: 0
Thanked 0 Times in 0 Posts
Default problems while verifying embedded timestamp in signature

Hello!

I have a p7m file generated using the BC provider. The certificate used for signing is a self signed certificate.

My signed file is generated using the following code
Code:
        List<X509Certificate> certList = new ArrayList<X509Certificate>();
        certList.add(getCertificate(alias));
        CertStore certstore = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), "BC");
        CMSSignedDataGenerator signer = new CMSSignedDataGenerator();
        signer.addSigner(getPK(alias), getCertificate(alias), CMSSignedDataGenerator.DIGEST_SHA1);
        signer.addCertificatesAndCRLs(certstore);
        
        CMSProcessable cmsUnsigned = new CMSProcessableByteArray(unsignedBytes);
        CMSSignedData signedData = signer.generate(cmsUnsigned, true, "BC");
        
        MessageDigest messageDigest = MessageDigest.getInstance("SHA1");
        messageDigest.update(unsignedBytes);
        byte hash[] = messageDigest.digest();
        
        signedData = addTimestamp(signedData, getTimeStampToken(1, hash));
After generating the signed file, I'm adding the timestamp from a TSA, using the addTimestamp method; the timestamp token is read using the getTimeStampToken method. Here is the listing of the 2 methods

Code:
    private static TimeStampToken getTimeStampToken(int TSA, byte[] digest) throws Exception {
        Security.addProvider (new org.bouncycastle.jce.provider.BouncyCastleProvider());

        PostMethod post = null;
        switch (TSA) {
        case 1:
            post = new PostMethod("http://www.edelweb.fr/cgi-bin/service-tsp");
            break;

        case 2:
            post = new PostMethod("http://tsp.iaik.at/tsp/TspRequest");
            break;


        case 3:
            post = new PostMethod("http://ns.szikszi.hu:8080/tsa");
            break;
        case 4:
            post = new PostMethod("http://time.certum.pl/");
            break;
        }

        TimeStampRequestGenerator reqGen = new TimeStampRequestGenerator();
        //request TSA to return certificate
        reqGen.setCertReq (true);
        //make a TSP request this is a dummy sha1 hash (20 zero bytes) and nonce=100
        TimeStampRequest request =
            reqGen.generate(TSPAlgorithms.SHA1,
//                    new byte[20], BigInteger.valueOf(100));
                    digest, BigInteger.valueOf(100));

        byte[] enc_req = request.getEncoded();
        ByteArrayInputStream bais = new ByteArrayInputStream(enc_req);
        post.setRequestBody(bais);
        post.setRequestContentLength (enc_req.length);
        post.setRequestHeader("Content-type","application/timestamp-query");

        HostConfiguration hc = new HostConfiguration();
        hc.setProxy("proxy.stfd.ro", 3128);

        HttpClient http_client = new HttpClient();
        http_client.executeMethod(hc, post);
        InputStream in = post.getResponseBodyAsStream();


        //read TSP response
        TimeStampResponse resp = new TimeStampResponse (in);
        resp.validate (request);
        System.out.println ("Timestamp validated");

        TimeStampToken  tsToken = resp.getTimeStampToken();
        SignerId signer_id = tsToken.getSID();


        BigInteger cert_serial_number = signer_id.getSerialNumber();

        System.out.println ("Signer ID serial "+signer_id.getSerialNumber());
        System.out.println ("Signer ID issuer "+signer_id.getIssuerAsString());


        CertStore cs = tsToken.getCertificatesAndCRLs ("Collection", "BC");


        Collection certs = cs.getCertificates (null);


        Iterator iter = certs.iterator();
        X509Certificate certificate = null;
        while (iter.hasNext()) {
            X509Certificate cert = (X509Certificate)iter.next();
            
            if (cert_serial_number != null) {
                if (cert.getSerialNumber().equals (cert_serial_number)) {
                    System.out.println ("using certificate with serial: "+cert.getSerialNumber());
                    certificate = cert;
                }
            } else {
                if (certificate == null) {
                    certificate = cert;
                }
            }
            System.out.println ("Certificate subject dn "+cert.getSubjectDN());
            System.out.println ("Certificate serial "+cert.getSerialNumber());
        }
        
        tsToken.validate(certificate, "BC");
        
        System.out.println ("TS info "+tsToken.getTimeStampInfo().getGenTime());
        System.out.println ("TS info "+tsToken.getTimeStampInfo().getAccuracy());
        System.out.println ("TS info "+tsToken.getTimeStampInfo().getNonce());
        return tsToken;
    }
Code:
    private static CMSSignedData addTimestamp(CMSSignedData signedData, TimeStampToken tok) throws Exception {
        Collection ss = signedData.getSignerInfos().getSigners();
        SignerInformation si = (SignerInformation) ss.iterator().next();
        
        ASN1InputStream asn1InputStream = new ASN1InputStream (tok.getEncoded());
        DERObject tstDER = asn1InputStream.readObject();
        DERSet ds = new DERSet(tstDER);
        Attribute a = new Attribute(new DERObjectIdentifier("1.2.840.113549.1.9.16.2.14"), ds);
        ASN1EncodableVector dv = new ASN1EncodableVector();
        dv.add(a);
        AttributeTable at = new AttributeTable(dv);
        si = SignerInformation.replaceUnsignedAttributes(si, at);
        ss.clear();
        ss.add(si);
        SignerInformationStore sis = new SignerInformationStore(ss);
        signedData = CMSSignedData.replaceSigners(signedData, sis);
        return signedData;
    }
The timestamp is set as an unsigned attribute, as stated in RFC3161, appendix A.

My problem is that when I try to verify as stated in the same RFC,
Quote:
The value of messageImprint field within TimeStampToken shall be a
hash of the value of signature field within SignerInfo for the signedData being time-stamped.
the following code returns false
Code:
    private boolean verifyTimestamp(CMSSignedData signature, TimeStampToken tto) throws Exception{
        System.out.println("******************************** start verify timestamp");
        
        readTimestampToken(signature);
        
        byte[] hashB = null;
        byte[] hashC = null;
        
        hashC = getHash(this.signedHash);
        
        hashB = tto.getTimeStampInfo().getMessageImprintDigest();
        
        System.out.println("******************************** end verify timestamp");
        
        return Arrays.equals(hashB, hashC);
    }
The timestamp token is being read from the signed file
Code:
    private TimeStampToken readTimestampToken(CMSSignedData signature) throws Exception{
        TimeStampToken tto = null;
        SignerInformationStore signers = signature.getSignerInfos();
        Collection c = signers.getSigners();
        Iterator it = c.iterator();
        SignerInformation signer = (SignerInformation)it.next();
        AttributeTable attrs = signer.getUnsignedAttributes();
        this.signedHash = signer.getSignature();
        Attribute att = attrs.get(PKCSObjectIdentifiers.id_aa_signatureTimeStampToken);
        
        DEREncodable dob = att.getAttrValues().getObjectAt(0);
        CMSSignedData signedData = new CMSSignedData(dob.getDERObject().getEncoded());
        tto = new TimeStampToken(signedData);
        
        return tto;
        
    }
Any idea what the problem might be?
I believe that I'm doing something wrong is when generating the signature with the timestamp but I cannot find it...

Any help would be appreciated!

Thank you,
Alexandru
 
Old September 21st, 2009, 08:26 AM
Registered User
 
Join Date: Aug 2007
Location: , , .
Posts: 6
Thanks: 0
Thanked 0 Times in 0 Posts
Default

problem solved

I had interpreting in the wrong way the RFC3161 that states that if adding the timestamp to a signature in a pkcs7 file the hash that needs to be sent to the TSA must be the hash of the signature field in the SignerInfo of the data.
Which is correct if I stay a little bit to think because the timestamp is for the signature, not for the unsigned data.

So, when creating the request for the TSA, the hash has to be the the hash for the signature.
 
Old September 1st, 2015, 10:03 PM
Registered User
Points: 3, Level: 1
Points: 3, Level: 1 Points: 3, Level: 1 Points: 3, Level: 1
Activity: 0%
Activity: 0% Activity: 0% Activity: 0%
 
Join Date: Sep 2015
Posts: 1
Thanks: 0
Thanked 0 Times in 0 Posts
Default Help support

Quote:
Originally Posted by fulgerica View Post
problem solved

I had interpreting in the wrong way the RFC3161 that states that if adding the timestamp to a signature in a pkcs7 file the hash that needs to be sent to the TSA must be the hash of the signature field in the SignerInfo of the data.
Which is correct if I stay a little bit to think because the timestamp is for the signature, not for the unsigned data.

So, when creating the request for the TSA, the hash has to be the the hash for the signature.
You can post full code give me , thank you very much




Similar Threads
Thread Thread Starter Forum Replies Last Post
Problems transforming embedded html tags Brad Harrington XSLT 1 February 10th, 2009 04:53 PM
Verifying Username/Password...Please wait. cancer10 Classic ASP Databases 0 March 8th, 2007 01:19 AM
Verifying Zip Code Range stevenyoo321 Access VBA 1 February 5th, 2007 08:40 AM
Verifying uploaded File Size in Client-side Ushhh ASP.NET 1.0 and 1.1 Professional 5 August 30th, 2006 07:13 AM
Verifying Table Existence kpp01 Access 3 January 5th, 2005 07:23 AM





Powered by vBulletin®
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
Copyright (c) 2020 John Wiley & Sons, Inc.