/// <inheritdoc /> public byte[] Decrypt(byte[] data) { foreach (var pkcsStore in _allSenderCertificates) { var certAlias = pkcsStore.Aliases.Cast<string>().First(x => pkcsStore.IsKeyEntry(x)); var certEntry = pkcsStore.GetCertificate(certAlias); var cert = certEntry.Certificate; var envelopedData = new CmsEnvelopedData(data); var recepientInfos = envelopedData.GetRecipientInfos(); var recepientId = new RecipientID() { Issuer = cert.IssuerDN, SerialNumber = cert.SerialNumber }; var recepient = recepientInfos[recepientId]; if (recepient == null) continue; var privKeyEntry = pkcsStore.GetKey(certAlias); var privKey = privKeyEntry.Key; var decryptedData = recepient.GetContent(privKey); var sig = new CmsSignedData(decryptedData); var sigInfos = sig.GetSignerInfos(); var signerId = new SignerID() { Issuer = _receiverCertificate.IssuerDN, SerialNumber = _receiverCertificate.SerialNumber }; var signer = sigInfos.GetFirstSigner(signerId); if (!signer.Verify(_receiverCertificate)) throw new ExtraEncryptionException("Failed to verify the signature."); var verifiedData = new MemoryStream(); sig.SignedContent.Write(verifiedData); return verifiedData.ToArray(); } throw new ExtraEncryptionException("No certificate for decryption found."); }
/** * @throws IOException */ private void ReadDecryptedDocObj() { if (encrypted) return; PdfObject encDic = trailer.Get(PdfName.ENCRYPT); if (encDic == null || encDic.ToString().Equals("null")) return; encryptionError = true; byte[] encryptionKey = null; encrypted = true; PdfDictionary enc = (PdfDictionary)GetPdfObject(encDic); String s; PdfObject o; PdfArray documentIDs = trailer.GetAsArray(PdfName.ID); byte[] documentID = null; if (documentIDs != null) { o = documentIDs[0]; strings.Remove((PdfString)o); s = o.ToString(); documentID = DocWriter.GetISOBytes(s); if (documentIDs.Size > 1) strings.Remove((PdfString)documentIDs[1]); } // just in case we have a broken producer if (documentID == null) documentID = new byte[0]; byte[] uValue = null; byte[] oValue = null; int cryptoMode = PdfWriter.STANDARD_ENCRYPTION_40; int lengthValue = 0; PdfObject filter = GetPdfObjectRelease(enc.Get(PdfName.FILTER)); if (filter.Equals(PdfName.STANDARD)) { s = enc.Get(PdfName.U).ToString(); strings.Remove((PdfString)enc.Get(PdfName.U)); uValue = DocWriter.GetISOBytes(s); s = enc.Get(PdfName.O).ToString(); strings.Remove((PdfString)enc.Get(PdfName.O)); oValue = DocWriter.GetISOBytes(s); if (enc.Contains(PdfName.OE)) strings.Remove((PdfString)enc.Get(PdfName.OE)); if (enc.Contains(PdfName.UE)) strings.Remove((PdfString)enc.Get(PdfName.UE)); if (enc.Contains(PdfName.PERMS)) strings.Remove((PdfString)enc.Get(PdfName.PERMS)); o = enc.Get(PdfName.P); if (!o.IsNumber()) throw new InvalidPdfException(MessageLocalization.GetComposedMessage("illegal.p.value")); pValue = ((PdfNumber)o).IntValue; o = enc.Get(PdfName.R); if (!o.IsNumber()) throw new InvalidPdfException(MessageLocalization.GetComposedMessage("illegal.r.value")); rValue = ((PdfNumber)o).IntValue; switch (rValue) { case 2: cryptoMode = PdfWriter.STANDARD_ENCRYPTION_40; break; case 3: o = enc.Get(PdfName.LENGTH); if (!o.IsNumber()) throw new InvalidPdfException(MessageLocalization.GetComposedMessage("illegal.length.value")); lengthValue = ( (PdfNumber) o).IntValue; if (lengthValue > 128 || lengthValue < 40 || lengthValue % 8 != 0) throw new InvalidPdfException(MessageLocalization.GetComposedMessage("illegal.length.value")); cryptoMode = PdfWriter.STANDARD_ENCRYPTION_128; break; case 4: PdfDictionary dic = (PdfDictionary)enc.Get(PdfName.CF); if (dic == null) throw new InvalidPdfException(MessageLocalization.GetComposedMessage("cf.not.found.encryption")); dic = (PdfDictionary)dic.Get(PdfName.STDCF); if (dic == null) throw new InvalidPdfException(MessageLocalization.GetComposedMessage("stdcf.not.found.encryption")); if (PdfName.V2.Equals(dic.Get(PdfName.CFM))) cryptoMode = PdfWriter.STANDARD_ENCRYPTION_128; else if (PdfName.AESV2.Equals(dic.Get(PdfName.CFM))) cryptoMode = PdfWriter.ENCRYPTION_AES_128; else throw new UnsupportedPdfException(MessageLocalization.GetComposedMessage("no.compatible.encryption.found")); PdfObject em = enc.Get(PdfName.ENCRYPTMETADATA); if (em != null && em.ToString().Equals("false")) cryptoMode |= PdfWriter.DO_NOT_ENCRYPT_METADATA; break; case 5: cryptoMode = PdfWriter.ENCRYPTION_AES_256; PdfObject em5 = enc.Get(PdfName.ENCRYPTMETADATA); if (em5 != null && em5.ToString().Equals("false")) cryptoMode |= PdfWriter.DO_NOT_ENCRYPT_METADATA; break; default: throw new UnsupportedPdfException(MessageLocalization.GetComposedMessage("unknown.encryption.type.r.eq.1", rValue)); } } else if (filter.Equals(PdfName.PUBSEC)) { bool foundRecipient = false; byte[] envelopedData = null; PdfArray recipients = null; o = enc.Get(PdfName.V); if (!o.IsNumber()) throw new InvalidPdfException(MessageLocalization.GetComposedMessage("illegal.v.value")); int vValue = ((PdfNumber)o).IntValue; switch(vValue) { case 1: cryptoMode = PdfWriter.STANDARD_ENCRYPTION_40; lengthValue = 40; recipients = (PdfArray)enc.Get(PdfName.RECIPIENTS); break; case 2: o = enc.Get(PdfName.LENGTH); if (!o.IsNumber()) throw new InvalidPdfException(MessageLocalization.GetComposedMessage("illegal.length.value")); lengthValue = ( (PdfNumber) o).IntValue; if (lengthValue > 128 || lengthValue < 40 || lengthValue % 8 != 0) throw new InvalidPdfException(MessageLocalization.GetComposedMessage("illegal.length.value")); cryptoMode = PdfWriter.STANDARD_ENCRYPTION_128; recipients = (PdfArray)enc.Get(PdfName.RECIPIENTS); break; case 4: case 5: PdfDictionary dic = (PdfDictionary)enc.Get(PdfName.CF); if (dic == null) throw new InvalidPdfException(MessageLocalization.GetComposedMessage("cf.not.found.encryption")); dic = (PdfDictionary)dic.Get(PdfName.DEFAULTCRYPTFILTER); if (dic == null) throw new InvalidPdfException(MessageLocalization.GetComposedMessage("defaultcryptfilter.not.found.encryption")); if (PdfName.V2.Equals(dic.Get(PdfName.CFM))) { cryptoMode = PdfWriter.STANDARD_ENCRYPTION_128; lengthValue = 128; } else if (PdfName.AESV2.Equals(dic.Get(PdfName.CFM))) { cryptoMode = PdfWriter.ENCRYPTION_AES_128; lengthValue = 128; } else if (PdfName.AESV3.Equals(dic.Get(PdfName.CFM))) { cryptoMode = PdfWriter.ENCRYPTION_AES_256; lengthValue = 256; } else throw new UnsupportedPdfException(MessageLocalization.GetComposedMessage("no.compatible.encryption.found")); PdfObject em = dic.Get(PdfName.ENCRYPTMETADATA); if (em != null && em.ToString().Equals("false")) cryptoMode |= PdfWriter.DO_NOT_ENCRYPT_METADATA; recipients = (PdfArray)dic.Get(PdfName.RECIPIENTS); break; default: throw new UnsupportedPdfException(MessageLocalization.GetComposedMessage("unknown.encryption.type.v.eq.1", vValue)); } for (int i = 0; i<recipients.Size; i++) { PdfObject recipient = recipients[i]; if (recipient is PdfString) strings.Remove((PdfString)recipient); CmsEnvelopedData data = null; data = new CmsEnvelopedData(recipient.GetBytes()); foreach (RecipientInformation recipientInfo in data.GetRecipientInfos().GetRecipients()) { if (recipientInfo.RecipientID.Match(certificate) && !foundRecipient) { envelopedData = recipientInfo.GetContent(certificateKey); foundRecipient = true; } } } if (!foundRecipient || envelopedData == null) { throw new UnsupportedPdfException(MessageLocalization.GetComposedMessage("bad.certificate.and.key")); } IDigest sh; if ((cryptoMode & PdfWriter.ENCRYPTION_MASK) == PdfWriter.ENCRYPTION_AES_256) sh = DigestUtilities.GetDigest("SHA-256"); else sh = DigestUtilities.GetDigest("SHA-1"); sh.BlockUpdate(envelopedData, 0, 20); for (int i=0; i<recipients.Size; i++) { byte[] encodedRecipient = recipients[i].GetBytes(); sh.BlockUpdate(encodedRecipient, 0, encodedRecipient.Length); } if ((cryptoMode & PdfWriter.DO_NOT_ENCRYPT_METADATA) != 0) sh.BlockUpdate(PdfEncryption.metadataPad, 0, PdfEncryption.metadataPad.Length); encryptionKey = new byte[sh.GetDigestSize()]; sh.DoFinal(encryptionKey, 0); } decrypt = new PdfEncryption(); decrypt.SetCryptoMode(cryptoMode, lengthValue); if (filter.Equals(PdfName.STANDARD)) { if (rValue == 5) { ownerPasswordUsed = decrypt.ReadKey(enc, password); pValue = decrypt.GetPermissions(); } else { //check by owner password decrypt.SetupByOwnerPassword(documentID, password, uValue, oValue, pValue); if (!EqualsArray(uValue, decrypt.userKey, (rValue == 3 || rValue == 4) ? 16 : 32)) { //check by user password decrypt.SetupByUserPassword(documentID, password, oValue, pValue); if (!EqualsArray(uValue, decrypt.userKey, (rValue == 3 || rValue == 4) ? 16 : 32)) { throw new BadPasswordException(MessageLocalization.GetComposedMessage("bad.user.password")); } } else ownerPasswordUsed = true; } } else if (filter.Equals(PdfName.PUBSEC)) { if ((cryptoMode & PdfWriter.ENCRYPTION_MASK) == PdfWriter.ENCRYPTION_AES_256) decrypt.SetKey(encryptionKey); else decrypt.SetupByEncryptionKey(encryptionKey, lengthValue); ownerPasswordUsed = true; } for (int k = 0; k < strings.Count; ++k) { PdfString str = strings[k]; str.Decrypt(this); } if (encDic.IsIndirect()) { cryptoRef = (PRIndirectReference)encDic; xrefObj[cryptoRef.Number] = null; } encryptionError = false; }
private void VerifyECMqvKeyAgreeVectors( AsymmetricKeyParameter privKey, string wrapAlg, byte[] message) { byte[] data = Hex.Decode("504b492d4320434d5320456e76656c6f706564446174612053616d706c65"); CmsEnvelopedData ed = new CmsEnvelopedData(message); RecipientInformationStore recipients = ed.GetRecipientInfos(); ICollection c = recipients.GetRecipients(); Assert.AreEqual(wrapAlg, ed.EncryptionAlgOid); Assert.AreEqual(1, c.Count); foreach (RecipientInformation recipient in c) { Assert.AreEqual("1.3.133.16.840.63.0.16", recipient.KeyEncryptionAlgOid); byte[] recData = recipient.GetContent(privKey); Assert.IsTrue(Arrays.AreEqual(data, recData)); } }
public void TestOriginatorInfo() { CmsEnvelopedData env = new CmsEnvelopedData(CmsSampleMessages.originatorMessage); RecipientInformationStore recipients = env.GetRecipientInfos(); Assert.AreEqual(CmsEnvelopedDataGenerator.DesEde3Cbc, env.EncryptionAlgOid); }
public void TestRfc4134Ex5_2() { byte[] data = Hex.Decode("5468697320697320736f6d652073616d706c6520636f6e74656e742e"); // KeyFactory kFact = KeyFactory.GetInstance("RSA"); // Key key = kFact.generatePrivate(new PKCS8EncodedKeySpec(bobPrivRsaEncrypt)); AsymmetricKeyParameter key = PrivateKeyFactory.CreateKey(bobPrivRsaEncrypt); CmsEnvelopedData ed = new CmsEnvelopedData(rfc4134ex5_2); RecipientInformationStore recipients = ed.GetRecipientInfos(); Assert.AreEqual("1.2.840.113549.3.2", ed.EncryptionAlgOid); ICollection c = recipients.GetRecipients(); IEnumerator e = c.GetEnumerator(); if (e.MoveNext()) { do { RecipientInformation recipient = (RecipientInformation) e.Current; if (recipient is KeyTransRecipientInformation) { byte[] recData = recipient.GetContent(key); Assert.IsTrue(Arrays.AreEqual(data, recData)); } } while (e.MoveNext()); } else { Assert.Fail("no recipient found"); } }
public void TestRfc4134Ex5_1() { byte[] data = Hex.Decode("5468697320697320736f6d652073616d706c6520636f6e74656e742e"); // KeyFactory kFact = KeyFactory.GetInstance("RSA"); // Key key = kFact.generatePrivate(new PKCS8EncodedKeySpec(bobPrivRsaEncrypt)); AsymmetricKeyParameter key = PrivateKeyFactory.CreateKey(bobPrivRsaEncrypt); CmsEnvelopedData ed = new CmsEnvelopedData(rfc4134ex5_1); RecipientInformationStore recipients = ed.GetRecipientInfos(); Assert.AreEqual("1.2.840.113549.3.7", ed.EncryptionAlgOid); ICollection c = recipients.GetRecipients(); Assert.AreEqual(1, c.Count); foreach (RecipientInformation recipient in c) { byte[] recData = recipient.GetContent(key); Assert.IsTrue(Arrays.AreEqual(data, recData)); } }
public void TestErroneousKek() { byte[] data = Encoding.ASCII.GetBytes("WallaWallaWashington"); KeyParameter kek = ParameterUtilities.CreateKeyParameter( "AES", new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }); CmsEnvelopedData ed = new CmsEnvelopedData(oldKEK); RecipientInformationStore recipients = ed.GetRecipientInfos(); Assert.AreEqual(ed.EncryptionAlgOid, CmsEnvelopedDataGenerator.DesEde3Cbc); ICollection c = recipients.GetRecipients(); Assert.AreEqual(1, c.Count); foreach (RecipientInformation recipient in c) { Assert.AreEqual(recipient.KeyEncryptionAlgOid, NistObjectIdentifiers.IdAes128Wrap.Id); byte[] recData = recipient.GetContent(kek); Assert.IsTrue(Arrays.AreEqual(data, recData)); } }
/** * @throws IOException */ private void ReadDecryptedDocObj() { if (encrypted) return; PdfObject encDic = trailer.Get(PdfName.ENCRYPT); if (encDic == null || encDic.ToString().Equals("null")) return; encryptionError = true; byte[] encryptionKey = null; encrypted = true; PdfDictionary enc = (PdfDictionary)GetPdfObject(encDic); String s; PdfObject o; PdfArray documentIDs = trailer.GetAsArray(PdfName.ID); byte[] documentID = null; if (documentIDs != null) { o = documentIDs[0]; strings.Remove(o); s = o.ToString(); documentID = DocWriter.GetISOBytes(s); if (documentIDs.Size > 1) strings.Remove(documentIDs[1]); } // just in case we have a broken producer if (documentID == null) documentID = new byte[0]; byte[] uValue = null; byte[] oValue = null; int cryptoMode = PdfWriter.STANDARD_ENCRYPTION_40; int lengthValue = 0; PdfObject filter = GetPdfObjectRelease(enc.Get(PdfName.FILTER)); if (filter.Equals(PdfName.STANDARD)) { s = enc.Get(PdfName.U).ToString(); strings.Remove(enc.Get(PdfName.U)); uValue = DocWriter.GetISOBytes(s); s = enc.Get(PdfName.O).ToString(); strings.Remove(enc.Get(PdfName.O)); oValue = DocWriter.GetISOBytes(s); o = enc.Get(PdfName.P); if (!o.IsNumber()) throw new InvalidPdfException("Illegal P value."); pValue = ((PdfNumber)o).IntValue; o = enc.Get(PdfName.R); if (!o.IsNumber()) throw new InvalidPdfException("Illegal R value."); rValue = ((PdfNumber)o).IntValue; switch (rValue) { case 2: cryptoMode = PdfWriter.STANDARD_ENCRYPTION_40; break; case 3: o = enc.Get(PdfName.LENGTH); if (!o.IsNumber()) throw new InvalidPdfException("Illegal Length value."); lengthValue = ( (PdfNumber) o).IntValue; if (lengthValue > 128 || lengthValue < 40 || lengthValue % 8 != 0) throw new InvalidPdfException("Illegal Length value."); cryptoMode = PdfWriter.STANDARD_ENCRYPTION_128; break; case 4: PdfDictionary dic = (PdfDictionary)enc.Get(PdfName.CF); if (dic == null) throw new InvalidPdfException("/CF not found (encryption)"); dic = (PdfDictionary)dic.Get(PdfName.STDCF); if (dic == null) throw new InvalidPdfException("/StdCF not found (encryption)"); if (PdfName.V2.Equals(dic.Get(PdfName.CFM))) cryptoMode = PdfWriter.STANDARD_ENCRYPTION_128; else if (PdfName.AESV2.Equals(dic.Get(PdfName.CFM))) cryptoMode = PdfWriter.ENCRYPTION_AES_128; else throw new UnsupportedPdfException("No compatible encryption found"); PdfObject em = enc.Get(PdfName.ENCRYPTMETADATA); if (em != null && em.ToString().Equals("false")) cryptoMode |= PdfWriter.DO_NOT_ENCRYPT_METADATA; break; default: throw new UnsupportedPdfException("Unknown encryption type R = " + rValue); } } else if (filter.Equals(PdfName.PUBSEC)) { bool foundRecipient = false; byte[] envelopedData = null; PdfArray recipients = null; o = enc.Get(PdfName.V); if (!o.IsNumber()) throw new InvalidPdfException("Illegal V value."); int vValue = ((PdfNumber)o).IntValue; switch(vValue) { case 1: cryptoMode = PdfWriter.STANDARD_ENCRYPTION_40; lengthValue = 40; recipients = (PdfArray)enc.Get(PdfName.RECIPIENTS); break; case 2: o = enc.Get(PdfName.LENGTH); if (!o.IsNumber()) throw new InvalidPdfException("Illegal Length value."); lengthValue = ( (PdfNumber) o).IntValue; if (lengthValue > 128 || lengthValue < 40 || lengthValue % 8 != 0) throw new InvalidPdfException("Illegal Length value."); cryptoMode = PdfWriter.STANDARD_ENCRYPTION_128; recipients = (PdfArray)enc.Get(PdfName.RECIPIENTS); break; case 4: PdfDictionary dic = (PdfDictionary)enc.Get(PdfName.CF); if (dic == null) throw new InvalidPdfException("/CF not found (encryption)"); dic = (PdfDictionary)dic.Get(PdfName.DEFAULTCRYPTFILTER); if (dic == null) throw new InvalidPdfException("/DefaultCryptFilter not found (encryption)"); if (PdfName.V2.Equals(dic.Get(PdfName.CFM))) { cryptoMode = PdfWriter.STANDARD_ENCRYPTION_128; lengthValue = 128; } else if (PdfName.AESV2.Equals(dic.Get(PdfName.CFM))) { cryptoMode = PdfWriter.ENCRYPTION_AES_128; lengthValue = 128; } else throw new UnsupportedPdfException("No compatible encryption found"); PdfObject em = dic.Get(PdfName.ENCRYPTMETADATA); if (em != null && em.ToString().Equals("false")) cryptoMode |= PdfWriter.DO_NOT_ENCRYPT_METADATA; recipients = (PdfArray)dic.Get(PdfName.RECIPIENTS); break; default: throw new UnsupportedPdfException("Unknown encryption type V = " + rValue); } for (int i = 0; i<recipients.Size; i++) { PdfObject recipient = recipients[i]; strings.Remove(recipient); CmsEnvelopedData data = null; data = new CmsEnvelopedData(recipient.GetBytes()); foreach (RecipientInformation recipientInfo in data.GetRecipientInfos().GetRecipients()) { if (recipientInfo.RecipientID.Match(certificate) && !foundRecipient) { envelopedData = recipientInfo.GetContent(certificateKey); foundRecipient = true; } } } if (!foundRecipient || envelopedData == null) { throw new UnsupportedPdfException("Bad certificate and key."); } SHA1 sh = new SHA1CryptoServiceProvider(); sh.TransformBlock(envelopedData, 0, 20, envelopedData, 0); for (int i=0; i<recipients.Size; i++) { byte[] encodedRecipient = recipients[i].GetBytes(); sh.TransformBlock(encodedRecipient, 0, encodedRecipient.Length, encodedRecipient, 0); } if ((cryptoMode & PdfWriter.DO_NOT_ENCRYPT_METADATA) != 0) sh.TransformBlock(PdfEncryption.metadataPad, 0, PdfEncryption.metadataPad.Length, PdfEncryption.metadataPad, 0); sh.TransformFinalBlock(envelopedData, 0, 0); encryptionKey = sh.Hash; } decrypt = new PdfEncryption(); decrypt.SetCryptoMode(cryptoMode, lengthValue); if (filter.Equals(PdfName.STANDARD)) { //check by owner password decrypt.SetupByOwnerPassword(documentID, password, uValue, oValue, pValue); if (!EqualsArray(uValue, decrypt.userKey, (rValue == 3 || rValue == 4) ? 16 : 32)) { //check by user password decrypt.SetupByUserPassword(documentID, password, oValue, pValue); if (!EqualsArray(uValue, decrypt.userKey, (rValue == 3 || rValue == 4) ? 16 : 32)) { throw new BadPasswordException("Bad user password"); } } else ownerPasswordUsed = true; } else if (filter.Equals(PdfName.PUBSEC)) { decrypt.SetupByEncryptionKey(encryptionKey, lengthValue); ownerPasswordUsed = true; } for (int k = 0; k < strings.Count; ++k) { PdfString str = (PdfString)strings[k]; str.Decrypt(this); } if (encDic.IsIndirect()) { cryptoRef = (PRIndirectReference)encDic; xrefObj[cryptoRef.Number] = null; } encryptionError = false; }