/// <summary> /// Декодирование зашифрованного сессионного ключа из BLOB /// в структуру. /// </summary> /// /// <param name="cspObject"><see cref="GostWrappedKeyObject"/></param> /// <param name="data">BLOB</param> /// /// <argnull name="data" /> /// <argnull name="cspObject" /> /// <exception cref="CryptographicException">При ошибках /// декодирования структуры.</exception> /// /// <intdoc><para>Аналог в MS отсутствует, часть реализации /// присутствует в ImportKey. </para></intdoc> /// /// <unmanagedperm action="LinkDemand" /> internal static void DecodeSimpleBlob(GostWrappedKeyObject cspObject, byte[] data) { if (data == null) { throw new ArgumentNullException("data"); } if (cspObject == null) { throw new ArgumentNullException("cspObject"); } if (data.Length < 16 + 0) { throw new CryptographicException(GostConstants.NTE_BAD_DATA); } // CRYPT_SIMPLEBLOB_HEADER_->BLOB_HEADER.aiKeyAlg ->4 uint aiKeyAlg = BitConverter.ToUInt32(data, 4); if (aiKeyAlg != GostConstants.CALG_G28147) { throw new CryptographicException(GostConstants.NTE_BAD_DATA); } // CRYPT_SIMPLEBLOB_HEADER_-> 8 (Magic, EncryptKeyAlgId) uint magic = BitConverter.ToUInt32(data, 8); if (magic != GostConstants.SIMPLEBLOB_MAGIC) { throw new CryptographicException(GostConstants.NTE_BAD_DATA); } uint EncryptKeyAlgId = BitConverter.ToUInt32(data, 12); if (EncryptKeyAlgId != GostConstants.CALG_G28147) { throw new CryptographicException(GostConstants.NTE_BAD_DATA); } // CRYPT_SIMPLEBLOB_->bSV int pos = 16; cspObject._ukm = new byte[GostConstants.SEANCE_VECTOR_LEN]; Array.Copy(data, pos, cspObject._ukm, 0, GostConstants.SEANCE_VECTOR_LEN); pos += GostConstants.SEANCE_VECTOR_LEN; // CRYPT_SIMPLEBLOB_->bEncryptedKey cspObject._encryptedKey = new byte[GostConstants.G28147_KEYLEN]; Array.Copy(data, pos, cspObject._encryptedKey, 0, GostConstants.G28147_KEYLEN); pos += GostConstants.G28147_KEYLEN; // CRYPT_SIMPLEBLOB_->bMacKey cspObject._mac = new byte[GostConstants.EXPORT_IMIT_SIZE]; Array.Copy(data, pos, cspObject._mac, 0, GostConstants.EXPORT_IMIT_SIZE); pos += GostConstants.EXPORT_IMIT_SIZE; // CRYPT_SIMPLEBLOB_->bEncryptionParamSet byte[] tmp = new byte[data.Length - pos]; Array.Copy(data, pos, tmp, 0, data.Length - pos); cspObject._encryptionParamSet = AsnHelper.DecodeGost28147_89_BlobParameters(tmp); }
/// <summary> /// Кодирование сессионного ключа в SIMPLE BLOB. /// </summary> /// /// <param name="cspObject">Зашифрованный сессионный ключ.</param> /// <param name="algid">Алгоритм зашифрованного ключа.</param> /// /// <returns>BLOB</returns> /// /// <exception cref="CryptographicException">При ошибках /// кодирования структуры.</exception> /// <argnull name="cspObject" /> /// /// <intdoc><para>Аналог в MS отсутствует, часть реализации /// присутствует в ImportKey. </para></intdoc> /// /// <unmanagedperm action="LinkDemand" /> internal static byte[] EncodeSimpleBlob(GostWrappedKeyObject cspObject, int algid) { if (cspObject == null) { throw new ArgumentNullException("cspObject"); } byte[] par = AsnHelper.EncodeGost28147_89_BlobParameters( cspObject._encryptionParamSet); byte[] ret = new byte[16 + GostConstants.SEANCE_VECTOR_LEN + GostConstants.G28147_KEYLEN + GostConstants.EXPORT_IMIT_SIZE + par.Length]; int pos = 0; // CRYPT_SIMPLEBLOB_->CRYPT_SIMPLEBLOB_HEADER ret[pos] = GostConstants.SIMPLEBLOB; pos++; ret[pos] = GostConstants.CSP_CUR_BLOB_VERSION; pos++; pos += 2; // Reserved byte[] balgid = BitConverter.GetBytes(algid); Array.Copy(balgid, 0, ret, pos, 4); pos += 4; byte[] magic = BitConverter.GetBytes(GostConstants.SIMPLEBLOB_MAGIC); Array.Copy(magic, 0, ret, pos, 4); pos += 4; byte[] ealgid = BitConverter.GetBytes(GostConstants.CALG_G28147); Array.Copy(ealgid, 0, ret, pos, 4); pos += 4; // CRYPT_SIMPLEBLOB_->bSV Array.Copy(cspObject._ukm, 0, ret, pos, GostConstants.SEANCE_VECTOR_LEN); pos += GostConstants.SEANCE_VECTOR_LEN; // CRYPT_SIMPLEBLOB_->bEncryptedKey Array.Copy(cspObject._encryptedKey, 0, ret, pos, GostConstants.G28147_KEYLEN); pos += GostConstants.G28147_KEYLEN; // CRYPT_SIMPLEBLOB_->bMacKey Array.Copy(cspObject._mac, 0, ret, pos, GostConstants.EXPORT_IMIT_SIZE); pos += GostConstants.EXPORT_IMIT_SIZE; // CRYPT_SIMPLEBLOB_->bEncryptionParamSet Array.Copy(par, 0, ret, pos, par.Length); return(ret); }