public byte[] goCrypting(String stringUnCrypted, String fileName) throws CryptageException {
    try {
      // Chargement de la chaine à crypter
      byte[] buffer = stringToByteArray(stringUnCrypted);

      // Chiffrement du document
      CMSEnvelopedDataGenerator gen = new CMSEnvelopedDataGenerator();
      // La variable cert correspond au certificat du destinataire
      // La clé publique de ce certificat servira à chiffrer la clé
      // symétrique
      RecipientInfoGenerator generator =
          new JceKeyTransRecipientInfoGenerator(getKeys(fileName).getCert()).setProvider("BC");
      gen.addRecipientInfoGenerator(generator);

      // Choix de l'algorithme à clé symétrique pour chiffrer le document.
      // AES est un standard. Vous pouvez donc l'utiliser sans crainte.
      // Il faut savoir qu'en france la taille maximum autorisée est de 128
      // bits pour les clés symétriques (ou clés secrètes)
      OutputEncryptor encryptor =
          new JceCMSContentEncryptorBuilder(CMSAlgorithm.AES128_CBC).setProvider("BC").build();
      CMSEnvelopedData envData = gen.generate(new CMSProcessableByteArray(buffer), encryptor);
      byte[] pkcs7envelopedData = envData.getEncoded();
      return pkcs7envelopedData;
    } catch (CryptageException e) {
      throw e;
    } catch (Exception e) {

      throw new CryptageException(
          "SilverCryptFactory.goCrypting", SilverpeasException.ERROR, "util.CRYPT_FAILED", e);
    }
  }
Example #2
0
  private CMSProcessable getContent(PkiMessage<?> message) throws MessageEncodingException {
    CMSProcessable signable;

    boolean hasMessageData = true;
    if (message instanceof CertRep) {
      CertRep response = (CertRep) message;
      if (response.getPkiStatus() != PkiStatus.SUCCESS) {
        hasMessageData = false;
      }
    }
    if (hasMessageData) {
      try {
        CMSEnvelopedData ed = encodeMessage(message);
        signable = new CMSProcessableByteArray(ed.getEncoded());
      } catch (IOException e) {
        throw new MessageEncodingException(e);
      }
    } else {
      signable = new CMSAbsentContent();
    }
    return signable;
  }
  public String goUnCrypting(byte[] stringCrypted, String fileName) throws CryptageException {
    try {
      // Chargement de la chaine à déchiffrer
      byte[] pkcs7envelopedData = stringCrypted;

      // Déchiffrement de la chaine
      CMSEnvelopedData ced = new CMSEnvelopedData(pkcs7envelopedData);
      @SuppressWarnings("unchecked")
      Collection<KeyTransRecipientInformation> recip = ced.getRecipientInfos().getRecipients();

      KeyTransRecipientInformation rinfo = recip.iterator().next();
      // privatekey est la clé privée permettant de déchiffrer la clé
      // secrète (symétrique)
      byte[] contents =
          rinfo.getContent(
              new JceKeyTransEnvelopedRecipient(this.getKeys(fileName).getPrivatekey()));
      return byteArrayToString(contents);
    } catch (CryptageException e) {
      throw e;
    } catch (Exception e) {
      throw new CryptageException(
          "SilverCryptFactory.goUnCrypting", SilverpeasException.ERROR, "util.UNCRYPT_FAILED", e);
    }
  }
  /**
   * Prepares everything to decrypt the document.
   *
   * <p>If {@link #decryptDocument(PDDocument, DecryptionMaterial)} is used, this method is called
   * from there. Only if decryption of single objects is needed this should be called instead.
   *
   * @param encDictionary encryption dictionary, can be retrieved via {@link
   *     PDDocument#getEncryptionDictionary()}
   * @param documentIDArray document id which is returned via {@link COSDocument#getDocumentID()}
   *     (not used by this handler)
   * @param decryptionMaterial Information used to decrypt the document.
   * @throws IOException If there is an error accessing data.
   * @throws CryptographyException If there is an error with decryption.
   */
  public void prepareForDecryption(
      PDEncryptionDictionary encDictionary,
      COSArray documentIDArray,
      DecryptionMaterial decryptionMaterial)
      throws CryptographyException, IOException {

    if (encDictionary.getLength() != 0) {
      this.keyLength = encDictionary.getLength();
    }

    if (!(decryptionMaterial instanceof PublicKeyDecryptionMaterial)) {
      throw new CryptographyException(
          "Provided decryption material is not compatible with the document");
    }

    PublicKeyDecryptionMaterial material = (PublicKeyDecryptionMaterial) decryptionMaterial;

    try {
      boolean foundRecipient = false;

      // the decrypted content of the enveloped data that match
      // the certificate in the decryption material provided
      byte[] envelopedData = null;

      // the bytes of each recipient in the recipients array
      byte[][] recipientFieldsBytes = new byte[encDictionary.getRecipientsLength()][];

      int recipientFieldsLength = 0;

      for (int i = 0; i < encDictionary.getRecipientsLength(); i++) {
        COSString recipientFieldString = encDictionary.getRecipientStringAt(i);
        byte[] recipientBytes = recipientFieldString.getBytes();
        CMSEnvelopedData data = new CMSEnvelopedData(recipientBytes);
        Iterator recipCertificatesIt = data.getRecipientInfos().getRecipients().iterator();
        while (recipCertificatesIt.hasNext()) {
          RecipientInformation ri = (RecipientInformation) recipCertificatesIt.next();
          // Impl: if a matching certificate was previously found it is an error,
          // here we just don't care about it
          if (ri.getRID().match(material.getCertificate()) && !foundRecipient) {
            foundRecipient = true;
            envelopedData = ri.getContent(material.getPrivateKey(), "BC");
          }
        }
        recipientFieldsBytes[i] = recipientBytes;
        recipientFieldsLength += recipientBytes.length;
      }
      if (!foundRecipient || envelopedData == null) {
        throw new CryptographyException("The certificate matches no recipient entry");
      }
      if (envelopedData.length != 24) {
        throw new CryptographyException("The enveloped data does not contain 24 bytes");
      }
      // now envelopedData contains:
      // - the 20 bytes seed
      // - the 4 bytes of permission for the current user

      byte[] accessBytes = new byte[4];
      System.arraycopy(envelopedData, 20, accessBytes, 0, 4);

      currentAccessPermission = new AccessPermission(accessBytes);
      currentAccessPermission.setReadOnly();

      // what we will put in the SHA1 = the seed + each byte contained in the recipients array
      byte[] sha1Input = new byte[recipientFieldsLength + 20];

      // put the seed in the sha1 input
      System.arraycopy(envelopedData, 0, sha1Input, 0, 20);

      // put each bytes of the recipients array in the sha1 input
      int sha1InputOffset = 20;
      for (int i = 0; i < recipientFieldsBytes.length; i++) {
        System.arraycopy(
            recipientFieldsBytes[i], 0, sha1Input, sha1InputOffset, recipientFieldsBytes[i].length);
        sha1InputOffset += recipientFieldsBytes[i].length;
      }

      MessageDigest md = MessageDigest.getInstance("SHA-1");
      byte[] mdResult = md.digest(sha1Input);

      // we have the encryption key ...
      encryptionKey = new byte[this.keyLength / 8];
      System.arraycopy(mdResult, 0, encryptionKey, 0, this.keyLength / 8);
    } catch (CMSException e) {
      throw new CryptographyException(e);
    } catch (KeyStoreException e) {
      throw new CryptographyException(e);
    } catch (NoSuchProviderException e) {
      throw new CryptographyException(e);
    } catch (NoSuchAlgorithmException e) {
      throw new CryptographyException(e);
    }
  }