protected virtual ParametersWithIV CreateParametersWithIV(KeyParameter key, byte[] buf, ref int off, int len) { ParametersWithIV ivParams = new ParametersWithIV(key, buf, off, len); off += len; return ivParams; }
public void Init( bool forWrapping, ICipherParameters parameters) { this.forWrapping = forWrapping; if (parameters is ParametersWithRandom) { parameters = ((ParametersWithRandom) parameters).Parameters; } if (parameters is KeyParameter) { this.param = (KeyParameter) parameters; } else if (parameters is ParametersWithIV) { ParametersWithIV pIV = (ParametersWithIV) parameters; byte[] iv = pIV.GetIV(); if (iv.Length != 8) throw new ArgumentException("IV length not equal to 8", "parameters"); this.iv = iv; this.param = (KeyParameter) pIV.Parameters; } else { // TODO Throw an exception for bad parameters? } }
public RecipientInfo Generate(KeyParameter contentEncryptionKey, SecureRandom random) { byte[] keyBytes = contentEncryptionKey.GetKey(); string rfc3211WrapperName = Helper.GetRfc3211WrapperName(keyEncryptionKeyOID); IWrapper keyWrapper = Helper.CreateWrapper(rfc3211WrapperName); // Note: In Java build, the IV is automatically generated in JCE layer int ivLength = rfc3211WrapperName.StartsWith("DESEDE") ? 8 : 16; byte[] iv = new byte[ivLength]; random.NextBytes(iv); ICipherParameters parameters = new ParametersWithIV(keyEncryptionKey, iv); keyWrapper.Init(true, new ParametersWithRandom(parameters, random)); Asn1OctetString encryptedKey = new DerOctetString( keyWrapper.Wrap(keyBytes, 0, keyBytes.Length)); DerSequence seq = new DerSequence( new DerObjectIdentifier(keyEncryptionKeyOID), new DerOctetString(iv)); AlgorithmIdentifier keyEncryptionAlgorithm = new AlgorithmIdentifier( PkcsObjectIdentifiers.IdAlgPwriKek, seq); return new RecipientInfo(new PasswordRecipientInfo( keyDerivationAlgorithm, keyEncryptionAlgorithm, encryptedKey)); }
/** * Base constructor. * * @param key key to be used by underlying cipher * @param macSize macSize in bits * @param nonce nonce to be used * @param associatedText associated text, if any */ public CcmParameters( KeyParameter key, int macSize, byte[] nonce, byte[] associatedText) : base(key, macSize, nonce, associatedText) { }
internal PbeMethod( SymmetricKeyAlgorithmTag encAlgorithm, S2k s2k, KeyParameter key) { this.encAlgorithm = encAlgorithm; this.s2k = s2k; this.key = key; }
/** * Base constructor. * * @param key key to be used by underlying cipher * @param macSize macSize in bits * @param nonce nonce to be used * @param associatedText associated text, if any */ public AeadParameters( KeyParameter key, int macSize, byte[] nonce, byte[] associatedText) { this.key = key; this.nonce = nonce; this.macSize = macSize; this.associatedText = associatedText; }
/** * Generate a new instance of an TlsMac. * * @param digest The digest to use. * @param key_block A byte-array where the key for this mac is located. * @param offset The number of bytes to skip, before the key starts in the buffer. * @param len The length of the key. */ public TlsMac( IDigest digest, byte[] key_block, int offset, int len) { this.mac = new HMac(digest); KeyParameter param = new KeyParameter(key_block, offset, len); this.mac.Init(param); this.seqNo = 0; }
public RecipientInfo Generate(KeyParameter contentEncryptionKey, SecureRandom random) { byte[] keyBytes = contentEncryptionKey.GetKey(); IWrapper keyWrapper = Helper.CreateWrapper(keyEncryptionAlgorithm.ObjectID.Id); keyWrapper.Init(true, new ParametersWithRandom(keyEncryptionKey, random)); Asn1OctetString encryptedKey = new DerOctetString( keyWrapper.Wrap(keyBytes, 0, keyBytes.Length)); return new RecipientInfo(new KekRecipientInfo(kekIdentifier, keyEncryptionAlgorithm, encryptedKey)); }
internal CmsTypedStream GetContentFromSessionKey( KeyParameter sKey) { ICmsReadable readable = secureReadable.GetReadable(sKey); try { return new CmsTypedStream(readable.GetInputStream()); } catch (IOException e) { throw new CmsException("error getting .", e); } }
/** * Method init * * @param forWrapping * @param param */ public void Init( bool forWrapping, ICipherParameters parameters) { this.forWrapping = forWrapping; this.engine = new CbcBlockCipher(new DesEdeEngine()); SecureRandom sr; if (parameters is ParametersWithRandom) { ParametersWithRandom pr = (ParametersWithRandom) parameters; parameters = pr.Parameters; sr = pr.Random; } else { sr = new SecureRandom(); } if (parameters is KeyParameter) { this.param = (KeyParameter) parameters; if (this.forWrapping) { // Hm, we have no IV but we want to wrap ?!? // well, then we have to create our own IV. this.iv = new byte[8]; sr.NextBytes(iv); this.paramPlusIV = new ParametersWithIV(this.param, this.iv); } } else if (parameters is ParametersWithIV) { if (!forWrapping) throw new ArgumentException("You should not supply an IV for unwrapping"); this.paramPlusIV = (ParametersWithIV) parameters; this.iv = this.paramPlusIV.GetIV(); this.param = (KeyParameter) this.paramPlusIV.Parameters; if (this.iv.Length != 8) throw new ArgumentException("IV is not 8 octets", "parameters"); } }
private void F( byte[] P, byte[] S, int c, byte[] iBuf, byte[] outBytes, int outOff) { byte[] state = new byte[hMac.GetMacSize()]; ICipherParameters param = new KeyParameter(P); hMac.Init(param); if (S != null) { hMac.BlockUpdate(S, 0, S.Length); } hMac.BlockUpdate(iBuf, 0, iBuf.Length); hMac.DoFinal(state, 0); Array.Copy(state, 0, outBytes, outOff, state.Length); for (int count = 1; count != c; count++) { hMac.Init(param); hMac.BlockUpdate(state, 0, state.Length); hMac.DoFinal(state, 0); for (int j = 0; j != state.Length; j++) { outBytes[outOff + j] ^= state[j]; } } }
public RecipientInfo Generate(KeyParameter contentEncryptionKey, SecureRandom random) { byte[] keyBytes = contentEncryptionKey.GetKey(); AlgorithmIdentifier keyEncryptionAlgorithm = info.AlgorithmID; IWrapper keyWrapper = Helper.CreateWrapper(keyEncryptionAlgorithm.ObjectID.Id); keyWrapper.Init(true, new ParametersWithRandom(recipientPublicKey, random)); byte[] encryptedKeyBytes = keyWrapper.Wrap(keyBytes, 0, keyBytes.Length); RecipientIdentifier recipId; if (recipientTbsCert != null) { IssuerAndSerialNumber issuerAndSerial = new IssuerAndSerialNumber( recipientTbsCert.Issuer, recipientTbsCert.SerialNumber.Value); recipId = new RecipientIdentifier(issuerAndSerial); } else { recipId = new RecipientIdentifier(subjectKeyIdentifier); } return new RecipientInfo(new KeyTransRecipientInfo(recipId, keyEncryptionAlgorithm, new DerOctetString(encryptedKeyBytes))); }
protected internal virtual AlgorithmIdentifier GetAlgorithmIdentifier( string encryptionOid, KeyParameter encKey, Asn1Encodable asn1Params, out ICipherParameters cipherParameters) { Asn1Object asn1Object; if (asn1Params != null) { asn1Object = asn1Params.ToAsn1Object(); cipherParameters = ParameterUtilities.GetCipherParameters( encryptionOid, encKey, asn1Object); } else { asn1Object = DerNull.Instance; cipherParameters = encKey; } return new AlgorithmIdentifier( new DerObjectIdentifier(encryptionOid), asn1Object); }
/** * add a KEK recipient. * @param key the secret key to use for wrapping * @param keyIdentifier the byte string that identifies the key */ public void AddKekRecipient( string keyAlgorithm, // TODO Remove need for this parameter KeyParameter key, KekIdentifier kekIdentifier) { KekRecipientInfoGenerator kekrig = new KekRecipientInfoGenerator(); kekrig.KekIdentifier = kekIdentifier; kekrig.KeyEncryptionKeyOID = keyAlgorithm; kekrig.KeyEncryptionKey = key; recipientInfoGenerators.Add(kekrig); }
/** * add a KEK recipient. * @param key the secret key to use for wrapping * @param keyIdentifier the byte string that identifies the key */ public void AddKekRecipient( string keyAlgorithm, // TODO Remove need for this parameter KeyParameter key, byte[] keyIdentifier) { AddKekRecipient(keyAlgorithm, key, new KekIdentifier(keyIdentifier, null, null)); }
public ICmsReadable GetReadable(KeyParameter key) { // TODO Create AEAD cipher instance to decrypt and calculate tag ( MAC) throw new CmsException("AuthEnveloped data decryption not yet implemented"); // RFC 5084 ASN.1 Module // -- Parameters for AlgorithmIdentifier // // CCMParameters ::= SEQUENCE { // aes-nonce OCTET STRING (SIZE(7..13)), // aes-ICVlen AES-CCM-ICVlen DEFAULT 12 } // // AES-CCM-ICVlen ::= INTEGER (4 | 6 | 8 | 10 | 12 | 14 | 16) // // GCMParameters ::= SEQUENCE { // aes-nonce OCTET STRING, -- recommended size is 12 octets // aes-ICVlen AES-GCM-ICVlen DEFAULT 12 } // // AES-GCM-ICVlen ::= INTEGER (12 | 13 | 14 | 15 | 16) }
public void Init( ICipherParameters parameters) { Reset(); if (!(parameters is KeyParameter || parameters is ParametersWithIV)) throw new ArgumentException("parameters must be an instance of KeyParameter or ParametersWithIV"); // KeyParameter must contain a double or triple length DES key, // however the underlying cipher is a single DES. The middle and // right key are used only in the final step. KeyParameter kp; if (parameters is KeyParameter) { kp = (KeyParameter)parameters; } else { kp = (KeyParameter)((ParametersWithIV)parameters).Parameters; } KeyParameter key1; byte[] keyvalue = kp.GetKey(); if (keyvalue.Length == 16) { // Double length DES key key1 = new KeyParameter(keyvalue, 0, 8); this.lastKey2 = new KeyParameter(keyvalue, 8, 8); this.lastKey3 = key1; } else if (keyvalue.Length == 24) { // Triple length DES key key1 = new KeyParameter(keyvalue, 0, 8); this.lastKey2 = new KeyParameter(keyvalue, 8, 8); this.lastKey3 = new KeyParameter(keyvalue, 16, 8); } else { throw new ArgumentException("Key must be either 112 or 168 bit long"); } if (parameters is ParametersWithIV) { cipher.Init(true, new ParametersWithIV(key1, ((ParametersWithIV)parameters).GetIV())); } else { cipher.Init(true, key1); } }
private byte[] EncryptBlock( byte[] input, int inOff, int inLen, byte[] z) { byte[] C = null; KeyParameter macKey = null; KdfParameters kParam = new KdfParameters(z, param.GetDerivationV()); int c_text_length = 0; int macKeySize = param.MacKeySize; if (cipher == null) // stream mode { byte[] Buffer = GenerateKdfBytes(kParam, inLen + (macKeySize / 8)); C = new byte[inLen + mac.GetMacSize()]; c_text_length = inLen; for (int i = 0; i != inLen; i++) { C[i] = (byte)(input[inOff + i] ^ Buffer[i]); } macKey = new KeyParameter(Buffer, inLen, (macKeySize / 8)); } else { int cipherKeySize = ((IesWithCipherParameters)param).CipherKeySize; byte[] Buffer = GenerateKdfBytes(kParam, (cipherKeySize / 8) + (macKeySize / 8)); cipher.Init(true, new KeyParameter(Buffer, 0, (cipherKeySize / 8))); c_text_length = cipher.GetOutputSize(inLen); byte[] tmp = new byte[c_text_length]; int len = cipher.ProcessBytes(input, inOff, inLen, tmp, 0); len += cipher.DoFinal(tmp, len); C = new byte[len + mac.GetMacSize()]; c_text_length = len; Array.Copy(tmp, 0, C, 0, len); macKey = new KeyParameter(Buffer, (cipherKeySize / 8), (macKeySize / 8)); } byte[] macIV = param.GetEncodingV(); mac.Init(macKey); mac.BlockUpdate(C, 0, c_text_length); mac.BlockUpdate(macIV, 0, macIV.Length); // // return the message and it's MAC // mac.DoFinal(C, c_text_length); return C; }
public virtual void Init( bool forEncryption, ICipherParameters parameters) { this.forEncryption = forEncryption; this.macBlock = null; if (parameters is AeadParameters) { AeadParameters param = (AeadParameters)parameters; nonce = param.GetNonce(); A = param.GetAssociatedText(); int macSizeBits = param.MacSize; if (macSizeBits < 96 || macSizeBits > 128 || macSizeBits % 8 != 0) { throw new ArgumentException("Invalid value for MAC size: " + macSizeBits); } macSize = macSizeBits / 8; keyParam = param.Key; } else if (parameters is ParametersWithIV) { ParametersWithIV param = (ParametersWithIV)parameters; nonce = param.GetIV(); A = null; macSize = 16; keyParam = (KeyParameter)param.Parameters; } else { throw new ArgumentException("invalid parameters passed to GCM"); } int bufLength = forEncryption ? BlockSize : (BlockSize + macSize); this.bufBlock = new byte[bufLength]; if (nonce == null || nonce.Length < 1) { throw new ArgumentException("IV must be at least 1 byte"); } if (A == null) { // Avoid lots of null checks A = new byte[0]; } // Cipher always used in forward mode cipher.Init(true, keyParam); // TODO This should be configurable by Init parameters // (but must be 16 if nonce length not 12) (BlockSize?) // this.tagLength = 16; this.H = new byte[BlockSize]; cipher.ProcessBlock(H, 0, H, 0); multiplier.Init(H); this.initS = gHASH(A); if (nonce.Length == 12) { this.J0 = new byte[16]; Array.Copy(nonce, 0, J0, 0, nonce.Length); this.J0[15] = 0x01; } else { this.J0 = gHASH(nonce); byte[] X = new byte[16]; packLength((ulong)nonce.Length * 8UL, X, 8); GcmUtilities.Xor(this.J0, X); multiplier.MultiplyH(this.J0); } this.S = Arrays.Clone(initS); this.counter = Arrays.Clone(J0); this.bufOff = 0; this.totalLength = 0; }
private byte[] DecryptBlock( byte[] in_enc, int inOff, int inLen, byte[] z) { byte[] M = null; KeyParameter macKey = null; KdfParameters kParam = new KdfParameters(z, param.GetDerivationV()); int macKeySize = param.MacKeySize; kdf.Init(kParam); inLen -= mac.GetMacSize(); if (cipher == null) // stream mode { byte[] Buffer = GenerateKdfBytes(kParam, inLen + (macKeySize / 8)); M = new byte[inLen]; for (int i = 0; i != inLen; i++) { M[i] = (byte)(in_enc[inOff + i] ^ Buffer[i]); } macKey = new KeyParameter(Buffer, inLen, (macKeySize / 8)); } else { int cipherKeySize = ((IesWithCipherParameters)param).CipherKeySize; byte[] Buffer = GenerateKdfBytes(kParam, (cipherKeySize / 8) + (macKeySize / 8)); cipher.Init(false, new KeyParameter(Buffer, 0, (cipherKeySize / 8))); M = cipher.DoFinal(in_enc, inOff, inLen); macKey = new KeyParameter(Buffer, (cipherKeySize / 8), (macKeySize / 8)); } byte[] macIV = param.GetEncodingV(); mac.Init(macKey); mac.BlockUpdate(in_enc, inOff, inLen); mac.BlockUpdate(macIV, 0, macIV.Length); mac.DoFinal(macBuf, 0); inOff += inLen; for (int t = 0; t < macBuf.Length; t++) { if (macBuf[t] != in_enc[inOff + t]) { throw (new InvalidCipherTextException("IMac codes failed to equal.")); } } return M; }
protected virtual KeyParameter CreateKeyParameter(byte[] buf, ref int off, int len) { KeyParameter key = new KeyParameter(buf, off, len); off += len; return key; }
private static void hmac_hash(IDigest digest, byte[] secret, byte[] seed, byte[] output) { HMac mac = new HMac(digest); KeyParameter param = new KeyParameter(secret); byte[] a = seed; int size = digest.GetDigestSize(); int iterations = (output.Length + size - 1) / size; byte[] buf = new byte[mac.GetMacSize()]; byte[] buf2 = new byte[mac.GetMacSize()]; for (int i = 0; i < iterations; i++) { mac.Init(param); mac.BlockUpdate(a, 0, a.Length); mac.DoFinal(buf, 0); a = buf; mac.Init(param); mac.BlockUpdate(a, 0, a.Length); mac.BlockUpdate(seed, 0, seed.Length); mac.DoFinal(buf2, 0); Array.Copy(buf2, 0, output, (size * i), System.Math.Min(size, output.Length - (size * i))); } }
private KeyParameter UnwrapSessionKey( string wrapAlg, KeyParameter agreedKey) { byte[] encKeyOctets = encryptedKey.GetOctets(); IWrapper keyCipher = WrapperUtilities.GetWrapper(wrapAlg); keyCipher.Init(false, agreedKey); byte[] sKeyBytes = keyCipher.Unwrap(encKeyOctets, 0, encKeyOctets.Length); return ParameterUtilities.CreateKeyParameter(GetContentAlgorithmName(), sKeyBytes); }
public ICmsReadable GetReadable(KeyParameter sKey) { string macAlg = this.algorithm.ObjectID.Id; // Asn1Object sParams = this.algorithm.Parameters.ToAsn1Object(); try { this.mac = MacUtilities.GetMac(macAlg); // FIXME Support for MAC algorithm parameters similar to cipher parameters // ASN1Object sParams = (ASN1Object)macAlg.getParameters(); // // if (sParams != null && !(sParams instanceof ASN1Null)) // { // AlgorithmParameters params = CMSEnvelopedHelper.INSTANCE.createAlgorithmParameters(macAlg.getObjectId().getId(), provider); // // params.init(sParams.getEncoded(), "ASN.1"); // // mac.init(sKey, params.getParameterSpec(IvParameterSpec.class)); // } // else { mac.Init(sKey); } // Asn1Object asn1Params = asn1Enc == null ? null : asn1Enc.ToAsn1Object(); // // ICipherParameters cipherParameters = sKey; // // if (asn1Params != null && !(asn1Params is Asn1Null)) // { // cipherParameters = ParameterUtilities.GetCipherParameters( // macAlg.ObjectID, cipherParameters, asn1Params); // } // else // { // string alg = macAlg.ObjectID.Id; // if (alg.Equals(CmsEnvelopedDataGenerator.DesEde3Cbc) // || alg.Equals(CmsEnvelopedDataGenerator.IdeaCbc) // || alg.Equals(CmsEnvelopedDataGenerator.Cast5Cbc)) // { // cipherParameters = new ParametersWithIV(cipherParameters, new byte[8]); // } // } // // mac.Init(cipherParameters); } catch (SecurityUtilityException e) { throw new CmsException("couldn't create cipher.", e); } catch (InvalidKeyException e) { throw new CmsException("key invalid in message.", e); } catch (IOException e) { throw new CmsException("error decoding algorithm parameters.", e); } try { return new CmsProcessableInputStream( new TeeInputStream( readable.GetInputStream(), new MacOutputStream(this.mac))); } catch (IOException e) { throw new CmsException("error reading content.", e); } }
private static AlgorithmIdentifier DetermineKeyEncAlg( string algorithm, KeyParameter key) { if (algorithm.StartsWith("DES")) { return new AlgorithmIdentifier( PkcsObjectIdentifiers.IdAlgCms3DesWrap, DerNull.Instance); } else if (algorithm.StartsWith("RC2")) { return new AlgorithmIdentifier( PkcsObjectIdentifiers.IdAlgCmsRC2Wrap, new DerInteger(58)); } else if (algorithm.StartsWith("AES")) { int length = key.GetKey().Length * 8; DerObjectIdentifier wrapOid; if (length == 128) { wrapOid = NistObjectIdentifiers.IdAes128Wrap; } else if (length == 192) { wrapOid = NistObjectIdentifiers.IdAes192Wrap; } else if (length == 256) { wrapOid = NistObjectIdentifiers.IdAes256Wrap; } else { throw new ArgumentException("illegal keysize in AES"); } return new AlgorithmIdentifier(wrapOid); // parameters absent } else if (algorithm.StartsWith("SEED")) { // parameters absent return new AlgorithmIdentifier(KisaObjectIdentifiers.IdNpkiAppCmsSeedWrap); } else if (algorithm.StartsWith("CAMELLIA")) { int length = key.GetKey().Length * 8; DerObjectIdentifier wrapOid; if (length == 128) { wrapOid = NttObjectIdentifiers.IdCamellia128Wrap; } else if (length == 192) { wrapOid = NttObjectIdentifiers.IdCamellia192Wrap; } else if (length == 256) { wrapOid = NttObjectIdentifiers.IdCamellia256Wrap; } else { throw new ArgumentException("illegal keysize in Camellia"); } return new AlgorithmIdentifier(wrapOid); // parameters must be absent } else { throw new ArgumentException("unknown algorithm"); } }
public ICmsReadable GetReadable(KeyParameter sKey) { try { this.cipher = CipherUtilities.GetCipher(this.algorithm.ObjectID); Asn1Encodable asn1Enc = this.algorithm.Parameters; Asn1Object asn1Params = asn1Enc == null ? null : asn1Enc.ToAsn1Object(); ICipherParameters cipherParameters = sKey; if (asn1Params != null && !(asn1Params is Asn1Null)) { cipherParameters = ParameterUtilities.GetCipherParameters( this.algorithm.ObjectID, cipherParameters, asn1Params); } else { string alg = this.algorithm.ObjectID.Id; if (alg.Equals(CmsEnvelopedDataGenerator.DesEde3Cbc) || alg.Equals(CmsEnvelopedDataGenerator.IdeaCbc) || alg.Equals(CmsEnvelopedDataGenerator.Cast5Cbc)) { cipherParameters = new ParametersWithIV(cipherParameters, new byte[8]); } } cipher.Init(false, cipherParameters); } catch (SecurityUtilityException e) { throw new CmsException("couldn't create cipher.", e); } catch (InvalidKeyException e) { throw new CmsException("key invalid in message.", e); } catch (IOException e) { throw new CmsException("error decoding algorithm parameters.", e); } try { return new CmsProcessableInputStream( new CipherStream(readable.GetInputStream(), cipher, null)); } catch (IOException e) { throw new CmsException("error reading content.", e); } }
public RecipientInfo Generate(KeyParameter contentEncryptionKey, SecureRandom random) { byte[] keyBytes = contentEncryptionKey.GetKey(); AsymmetricKeyParameter senderPublicKey = senderKeyPair.Public; ICipherParameters senderPrivateParams = senderKeyPair.Private; OriginatorIdentifierOrKey originator; try { originator = new OriginatorIdentifierOrKey( CreateOriginatorPublicKey(senderPublicKey)); } catch (IOException e) { throw new InvalidKeyException("cannot extract originator public key: " + e); } Asn1OctetString ukm = null; if (keyAgreementOID.Id.Equals(CmsEnvelopedGenerator.ECMqvSha1Kdf)) { try { IAsymmetricCipherKeyPairGenerator ephemKPG = GeneratorUtilities.GetKeyPairGenerator(keyAgreementOID); ephemKPG.Init( ((ECPublicKeyParameters)senderPublicKey).CreateKeyGenerationParameters(random)); AsymmetricCipherKeyPair ephemKP = ephemKPG.GenerateKeyPair(); ukm = new DerOctetString( new MQVuserKeyingMaterial( CreateOriginatorPublicKey(ephemKP.Public), null)); senderPrivateParams = new MqvPrivateParameters( (ECPrivateKeyParameters)senderPrivateParams, (ECPrivateKeyParameters)ephemKP.Private, (ECPublicKeyParameters)ephemKP.Public); } catch (IOException e) { throw new InvalidKeyException("cannot extract MQV ephemeral public key: " + e); } catch (SecurityUtilityException e) { throw new InvalidKeyException("cannot determine MQV ephemeral key pair parameters from public key: " + e); } } DerSequence paramSeq = new DerSequence( keyEncryptionOID, DerNull.Instance); AlgorithmIdentifier keyEncAlg = new AlgorithmIdentifier(keyAgreementOID, paramSeq); Asn1EncodableVector recipientEncryptedKeys = new Asn1EncodableVector(); foreach (X509Certificate recipientCert in recipientCerts) { TbsCertificateStructure tbsCert; try { tbsCert = TbsCertificateStructure.GetInstance( Asn1Object.FromByteArray(recipientCert.GetTbsCertificate())); } catch (Exception) { throw new ArgumentException("can't extract TBS structure from certificate"); } // TODO Should there be a SubjectKeyIdentifier-based alternative? IssuerAndSerialNumber issuerSerial = new IssuerAndSerialNumber( tbsCert.Issuer, tbsCert.SerialNumber.Value); KeyAgreeRecipientIdentifier karid = new KeyAgreeRecipientIdentifier(issuerSerial); ICipherParameters recipientPublicParams = recipientCert.GetPublicKey(); if (keyAgreementOID.Id.Equals(CmsEnvelopedGenerator.ECMqvSha1Kdf)) { recipientPublicParams = new MqvPublicParameters( (ECPublicKeyParameters)recipientPublicParams, (ECPublicKeyParameters)recipientPublicParams); } // Use key agreement to choose a wrap key for this recipient IBasicAgreement keyAgreement = AgreementUtilities.GetBasicAgreementWithKdf( keyAgreementOID, keyEncryptionOID.Id); keyAgreement.Init(new ParametersWithRandom(senderPrivateParams, random)); BigInteger agreedValue = keyAgreement.CalculateAgreement(recipientPublicParams); int keyEncryptionKeySize = GeneratorUtilities.GetDefaultKeySize(keyEncryptionOID) / 8; byte[] keyEncryptionKeyBytes = X9IntegerConverter.IntegerToBytes(agreedValue, keyEncryptionKeySize); KeyParameter keyEncryptionKey = ParameterUtilities.CreateKeyParameter( keyEncryptionOID, keyEncryptionKeyBytes); // Wrap the content encryption key with the agreement key IWrapper keyWrapper = Helper.CreateWrapper(keyEncryptionOID.Id); keyWrapper.Init(true, new ParametersWithRandom(keyEncryptionKey, random)); byte[] encryptedKeyBytes = keyWrapper.Wrap(keyBytes, 0, keyBytes.Length); Asn1OctetString encryptedKey = new DerOctetString(encryptedKeyBytes); recipientEncryptedKeys.Add(new RecipientEncryptedKey(karid, encryptedKey)); } return new RecipientInfo(new KeyAgreeRecipientInfo(originator, ukm, keyEncAlg, new DerSequence(recipientEncryptedKeys))); }
private byte[] CreateSessionInfo( SymmetricKeyAlgorithmTag algorithm, KeyParameter key) { byte[] keyBytes = key.GetKey(); byte[] sessionInfo = new byte[keyBytes.Length + 3]; sessionInfo[0] = (byte) algorithm; keyBytes.CopyTo(sessionInfo, 1); AddCheckSum(sessionInfo); return sessionInfo; }