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); } }
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); } }