• Revista PROGRAMAR: Já está disponível a edição #53 da revista programar. Faz já o download aqui!

vitortomaz

Cartão do Cidadão

7 mensagens neste tópico

boas,

já alguém conseguiu aceder ao certificado do cartão do cidadão para assinar documentos?

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

já ? Preciso de fazer isso com urgência lol estou a investigar se conseguir posto aqui alguma coisa.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Já, PDF's :)

Código quase chapado chapado da página que encontrei, de qualquer maneira ainda tenho um problema, se alguém me ajudar melhor: não consigo por isto a dar em 64bits/windows7 só 32bits/XP.

http://itextpdf.sourceforge.net/howtosign.html#introduction

Espero ter ajudado alguém, caso contrário é mais um pedaço de código para a posteridade.

    
  public static void SignHashed2(string filename, X509Certificate2 card)
        {
        

        
                    Org.BouncyCastle.X509.X509CertificateParser cp = new Org.BouncyCastle.X509.X509CertificateParser();
                    Org.BouncyCastle.X509.X509Certificate[] chain = new Org.BouncyCastle.X509.X509Certificate[] { cp.ReadCertificate(card.RawData) };



                    PdfReader reader = new PdfReader(filename);
                    string[] my_x = new string[2];
                    my_x = filename.Split('.');
                    my_x[0] = my_x[0].Replace("c:\\temp\\", "");
                    string x = my_x[0] + "__SIG" + ".pdf";
                    PdfStamper stp = PdfStamper.CreateSignature(reader, new FileStream(x, FileMode.Create), '\0');
                    PdfSignatureAppearance sap = stp.SignatureAppearance;
                    sap.SetVisibleSignature(new Rectangle(100, 100, 300, 200), 1, null);
                    sap.SignDate = DateTime.Now;
                    sap.SetCrypto(null, chain, null, null);
                    sap.Reason = "no reason";
                    sap.Location = "who cares";
// se tb quiseres certificar
                  //  sap.CertificationLevel = 2;
                    sap.Acro6Layers = true;
                    sap.Render = PdfSignatureAppearance.SignatureRender.NameAndDescription;
                    PdfSignature dic = new PdfSignature(PdfName.ADOBE_PPKMS, PdfName.ADBE_PKCS7_SHA1);
                    dic.Date = new PdfDate(sap.SignDate);
                  
                   
                    
                    dic.Name = PdfPKCS7.GetSubjectFields(chain[0]).GetField("CN");
                    if (sap.Reason != null)
                        dic.Reason = sap.Reason;
                    if (sap.Location != null)
                        dic.Location = sap.Location;
                    sap.CryptoDictionary = dic;
                    int csize = 4000;
                    Hashtable exc = new Hashtable();
                    exc[PdfName.CONTENTS] = csize * 2 + 2;
                    sap.PreClose(exc);

                    HashAlgorithm sha = new SHA1CryptoServiceProvider();

                    Stream s = sap.RangeStream;
                    int read = 0;
                    byte[] buff = new byte[8192];
                    while ((read = s.Read(buff, 0, 8192)) > 0)
                    {
                        sha.TransformBlock(buff, 0, read, buff, 0);
                    }
                    sha.TransformFinalBlock(buff, 0, 0);
                    byte[] pk = SignMsg(sha.Hash, card, false);

                    byte[] outc = new byte[csize];

                    PdfDictionary dic2 = new PdfDictionary();

                    Array.Copy(pk, 0, outc, 0, pk.Length);

                    dic2.Put(PdfName.CONTENTS, new PdfString(outc).SetHexWriting(true));
                    sap.Close(dic2);

     static public byte[] SignMsg(Byte[] msg, X509Certificate2 signerCert, bool detached)
        {
            //  Place message in a ContentInfo object.
            //  This is required to build a SignedCms object.
            ContentInfo contentInfo = new ContentInfo(msg);

            //  Instantiate SignedCms object with the ContentInfo above.
            //  Has default SubjectIdentifierType IssuerAndSerialNumber.
            SignedCms signedCms = new SignedCms(contentInfo, detached);

            //  Formulate a CmsSigner object for the signer.
            CmsSigner cmsSigner = new CmsSigner(signerCert);

            // Include the following line if the top certificate in the
            // smartcard is not in the trusted list.
            cmsSigner.IncludeOption = X509IncludeOption.EndCertOnly;

            //  Sign the CMS/PKCS #7 message. The second argument is
            //  needed to ask for the pin.
            signedCms.ComputeSignature(cmsSigner, false);

            //  Encode the CMS/PKCS #7 message.
            return signedCms.Encode();
        }
        
        }

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Esse código provavelmente poderá não dar... é PKCS7 e o cartão do cidadão funciona com PKCS11.... Não sei. comprei o leitor A uns dias vou começar a explorar e depois digo-vos algo :P

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Este código funciona bem, tirando em 64 bits, que se calhar tem a ver com isso que disseste... tenho que verificar.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

esquisito porque a pkcs11 usa uma chave de 1024bits mas pelos vistos a pkcs7 aceita de 512 a 1024. por tanto.... o mais interessante é que ja consegui fazer com que o sapo me pedisse o pin. mas não funfa não sei porque o.0

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Boas,

Estou a tentar criar uma pequena aplicação que, entre outra coisas, deveria (ou deverá) assinar um ficheiro (um challenge por exemplo) usando a chave privada do cartão do cidadão. Ou seja, terei que ir pelo pkcs#11. A documentação do middleware não ajuda muito, ao contrário documentação do CC belga. Lá encontrei um exemplo no entanto não estou a conseguir.

import java.io.ByteArrayInputStream; 
import java.io.IOException; 
import java.io.File; 
import java.io.FileInputStream; 
import java.io.DataInputStream; 
import java.io.FileOutputStream; 
import java.io.DataOutputStream; 

import sun.security.pkcs11.wrapper.CK_ATTRIBUTE; 
import sun.security.pkcs11.wrapper.CK_MECHANISM; 
import sun.security.pkcs11.wrapper.PKCS11; 
import sun.security.pkcs11.wrapper.PKCS11Constants; 
import sun.security.pkcs11.wrapper.PKCS11Exception; 

public class sign_p11  
{ 
  public static void main(String[] args) throws IOException, PKCS11Exception 
  { 
    PKCS11 pkcs11; 

    String osName = System.getProperty("os.name"); 

    try  
    { 

      if (-1 != osName.indexOf("Windows")) 
        pkcs11 = PKCS11.getInstance("pteidpkcs11.dll", "C_GetFunctionList", null, false); 
      else 
        pkcs11 = PKCS11.getInstance("libpteidpkcs11.so","C_GetFunctionList", null, false); 

      //Open the P11 session 
      long p11_session = pkcs11.C_OpenSession(0, PKCS11Constants.CKF_SERIAL_SESSION, null, null); 

      try  
      { 
        //Find the signature private key 
        CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[2]; 
        attributes[0] = new CK_ATTRIBUTE(); 
        attributes[0].type = PKCS11Constants.CKA_CLASS; 
        attributes[0].pValue = new Long(PKCS11Constants.CKO_PRIVATE_KEY); 
        attributes[1] = new CK_ATTRIBUTE(); 
        attributes[1].type = PKCS11Constants.CKA_ID; 
        attributes[1].pValue = 3; 

        pkcs11.C_FindObjectsInit(p11_session, attributes); 

        long[] keyHandles = pkcs11.C_FindObjects(p11_session, 1); 
        long signatureKey = keyHandles[0]; 

        pkcs11.C_FindObjectsFinal(p11_session); 

        //Open the data to sign 
        File file = null; 
        file = new File ("sign_p11.class"); 
        FileInputStream file_input = new FileInputStream (file); 
        DataInputStream data_in    = new DataInputStream (file_input); 

        byte[] data = new byte[(int)file.length()]; 
        data_in.read(data); 
        data_in.close(); 

        //Initialize the signature 
        CK_MECHANISM mechanism = new CK_MECHANISM(); 
        mechanism.mechanism = PKCS11Constants.CKM_SHA1_RSA_PKCS; 
        mechanism.pParameter = null; 
        pkcs11.C_SignInit(p11_session, mechanism, signatureKey); 

        //Sign the data 
        byte[] signature = pkcs11.C_Sign(p11_session, data); 

        //Write the signature into a file 
        file = new File ("sign_p11_java.sig"); 
        FileOutputStream file_output = new FileOutputStream (file); 
        DataOutputStream data_out = new DataOutputStream (file_output); 
        data_out.write(signature); 
        file_output.close(); 

        System.out.println("Signing successful"); 
      } 
      catch (Exception e) 
      { 
        System.out.println("[Catch] Exception: " + e.getMessage()); 
      } 
      finally  
      { 
        //Close the session 
        pkcs11.C_CloseSession(p11_session); 
      } 
    } 
    catch (Exception e) 
    { 
      System.out.println("[Catch] Exception: " + e.getMessage()); 
    } 
  } 

Penso que o problema está no template que crio no CK_ATTRIBUTE[] attributes e é usado no C_FindObjectsInit uma vez que "rebenta" quando tento aceder ao KeyHandles (o vector está vazio).

No entanto não estou a ver como resolver...

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!


Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.


Entrar Agora