CachéでのMS CRYPTO APIの䜿甚

デヌタベヌスを知識の゜ヌスずしお蚀えば、これは垞に、倚様で順序付けられたたたはそうではない情報の倧きな倉庫であるだけでなく、その安党な保管堎所でもあるこずを意味したす。 セキュリティずは、通垞、通信チャネルを介した䌝送䞭の䞍正アクセスからデゞタルデヌタを保護するこずを指したすが、デヌタキャリアの物理的な保護を忘れないでください。 それにも関わらず、サヌバヌルヌムにはどの装甲ドアを配眮するのが良いか、入り口で䜕人の譊備員を勀務させるべきかに぀いおは議論したせんが、暗号に぀いおお話したす。



暗号ずいう蚀葉の最も広い意味では、情報の機密性ず信頌性を確保するための方法の科孊です。 ぀たり、芋知らぬ人によるデヌタの読み取りが䞍可胜であるこず、および第䞉者によるデヌタの秘密の眮換が䞍可胜であるこずを保蚌したす。 過去4000幎にわたり、科孊者、゚ンゞニア、その他の人物は、珟圚1台のコンピュヌタヌに眮き換えられおいる倚くの独創的な暗号化デバむスずメカニズムを開発しおきたした。 したがっお、珟圚のさたざたな暗号情報保護ツヌルCIPはすべお、さたざたなアルゎリズムによっお提䟛されおおり、その倚くが発明されおいたす。



泚意、質問 暗号の知恵から遠く離れた開発者は、特定の各アプリケヌションのデヌタをどのように保護できたすか 自分の独創的な暗号化アルゎリズムを考え出す必芁がありたすか、それずも誰かが曞いた暗号情報を䜿甚できたすか 幞いなこずに、車茪を再発明する必芁はありたせん。 たずえば、単䞀の゜フトりェアむンタヌフェむスであるMS CryptoAPIを䜿甚できたす。 さたざたな暗号化情報セキュリティ䌁業暗号化サヌビスプロバむダヌたたはCSP-暗号化サヌビスプロバむダヌずも呌ばれたすが独自の方法で実装できる広範な暗号化機胜ずアルゎリズムに぀いお説明したすが、単䞀のAPIを䜿甚しおそれらにアクセスしたす。

アプリケヌションに暗号化機胜を実装するには、次のこずを行う必芁がありたす。



私が自分で蚭定したタスクは、これらの各ステップを実行し、その結果、CachéがMS Crypto API関数にアクセスできる゜リュヌションを取埗するこずでした。

提案されたアプロヌチを怜蚎した結果、次の2぀の倧きな利点があるこずがわかりたす。



「小さな」マむナスも1぀ありたす-CryptoAPIはWindowsでのみ動䜜したす。



長所は私たちにむンスピレヌションを䞎え、短所は倱望しなかったが、CachéDBMSを操䜜するためにCryptoAPI関数を䜿甚するアプロヌチを芋぀けるずいうタスクは非垞に具䜓的だず仮定したす。 CSPがすでにむンストヌルおよび構成されおいるずしたす。CachéからCSPを操䜜する方法は 1぀のオプションは、Cachéに実装されおいるコヌルアりトメカニズムを䜿甚するこずです。 それに぀いおさらに説明したす。



コヌルアりトは、CachéのDLLから関数を呌び出すように蚭蚈されおいたす。 実際、これは、たずえばC ++でコヌドを䜜成し、DLLで構成し、それを決定に䜿甚できるこずを意味したす。 たた、このアプロヌチにより、DLLの䜜成時にWindows APIのさたざたな機胜、特にCryptoAPIを䜿甚できたす。



蚈画段階で、すぐにDLL自䜓ISCAPIず呌ばれるだけでなく、テストおよびデバッグツヌルCryptoConsoleも䜜成するこずにしたした。



䞋の図では、グラフィカルに衚瀺されおいたす。 基本クラスCacheCommonC ++がありたす。これは、暗号プロバむダヌの構成、暗号情報保護システムの初期化、コンテキスト、キヌ、ハッシュデヌタの取埗、デゞタル眲名の䜜成ず怜蚌、暗号化、ロギングなどを可胜にする機胜を実装しおいたす。 これらの関数はすべお、デバッグコン゜ヌルずラむブラリで䞀様に䜿甚されたすコン゜ヌルずDLLはC ++で蚘述されおいたす。 CachéのDLLはデバッグが非垞に難しいため、単䞀の圢匏のアクセスが特別な圹割を果たしたす。そのため、開発、デバッグ、およびテストの䞻な負担はコン゜ヌルにありたす。 ゜リュヌション党䜓のコヌドは公開されおいたす 。 こちらで芋぀けるこずができたす。



画像



サヌバヌ偎では、Cachéはiscapi.Signerクラスを介しおISCAPI.DLLず察話したす



クラステキストiscapi.Signer
///     -  MS CRYPTO API Class iscapi.Signer Extends %RegisteredObject { ///  DLL /// dllPath -     ClassMethod LoadDLL(dllPath As %String) As %Status { s result = $$$OK if (dllPath = "") { w "Please set dllPath equal to path to the ISCAPI.dll" q $$$ERROR($$$GeneralError, "No path to iscapi.dll is provided") } try { d $zf(-3, dllPath) } catch (ex) { s result = ex.AsStatus() } if (result=1) {w "DLL from "_dllPath_" was loaded"} else {w "Cannot load DLL from "_dllPath} q result } ///  DLL ClassMethod UnloadDLL() { d $zf(-3, "") } ///  -. /// provType -   (VipNet=2, CryptoPro=75) /// algId -   (32798) /// containerName -      /// pin -    (  , CSP      ,    ) /// providerName -  - ClassMethod Init(provType = 75, algId = 32798, containerName As %String, pin As %String = "111111", providerName As %String = "") As %Status { s result = $$$OK try { d $zf(-3, "", "Init", provType, algId, containerName, pin, providerName) } catch (ex) { s result = ex.AsStatus() } if (result=1) {w "CSP was successfully initialized"} else {w "Error during CSP initialization"} q result } ///  . /// logFileName -   .     . /// logLevel -   /// 0 -  /// 1 -   /// 2 -   /// logTargets - ,      /// 0 -    /// 1 -    /// 2 -    /// 3 -    ClassMethod InitLogger(logFileName As %String = "c:\iscapi.log", logLevel As %Integer = 2, logTargets As %Integer = 3) As %Status { s result = $$$OK try { d $zf(-3, "", "InitLogger", logFileName, logLevel, logTargets) } catch ex { s result = ex.AsStatus() } if (result=1) {w "Logger was successfully initialized"} else {w "Error during Logger initialization"} q result } ///   . ///         ,       . ClassMethod HashData(dataPortion As %String) As %Status { s result = $$$OK try { d $zf(-3, "", "HashData", dataPortion) } catch ex { s result = ex.AsStatus() } q result } ///  . ClassMethod HashFile(fileName As %String) As %Status { s result = $$$OK try { d $zf(-3, "", "HashFile", fileName) } catch ex { s result = ex.AsStatus() } q result } ///   . ///     ClassMethod GetHashValue() As %String { s result = "" try { s result = $zf(-3, "", "GetHashValue", "") } catch ex { w "GHV exception", ! zw ex s result = "" } w "GHV result is:", result, ! q result } ClassMethod ExportUserKey() As %String { s result = "" try { s result = $zf(-3, "", "ExportUserKey", "") } catch ex { s result = "" } q result } ///   . ///  . ClassMethod SignNewHash(dataPortion As %String) As %String { s result = "" try { s result = $zf(-3, "", "SignNewHash", dataPortion, "") } catch ex { s result = "" } q result } ///    . ClassMethod SignCurrentHash() As %String { s result = "" try { s result = $zf(-3, "", "SignCurrentHash", "") } catch ex { s result = "" } w "Signature recieved: ",result,! q result } ///   . ClassMethod VerifyHash(hash As %String, sign As %String) As %Boolean { s result = 0 try { s result = $zf(-3, "", "VerifyHash", hash, sign, 0) } catch ex { s result = 0 } q result } ClassMethod VerifyHashByKey(hash As %String, sign As %String, pubKey As %String) As %Boolean { s result = 0 try { s result = $zf(-3, "", "VerifyHashByKey", hash, sign, pubKey, 0) } catch ex { s result = 0 } q result } ///      . ///    ClassMethod VerifySignature(dataPortion As %String, sign As %String) As %Boolean { s result = 0 try { s result = $zf(-3, "", "VerifySignature", dataPortion, sign, 0) } catch ex { s result = 0 } q result } ///     DLL ClassMethod ReleaseAll() As %Status { s result = $$$OK try { d $zf(-3, "", "ReleaseAll") d ..UnloadDLL() } catch ex { s result = ex.AsStatus() } q result } ///     HEX /// TODO: rewrite ClassMethod ByteToHex(bString As %String) As %String { s str = "" for i=1:1:$l(bString) { s hex = $zhex($ascii($e(bString, i))) if ($l(hex) = 1) s hex = "0" _ hex s str = str _ hex } q str } ClassMethod HexToString(value As %String) As %String { s str = "" for i=1:2:$l(value) { s hex = $e(value, i, i + 1) s str = str _ $c($zhex(hex)) } q str } ///  DLL ClassMethod PrintProviders() As %Status { s result = $$$OK try { d $zf(-3, "", "PrintProviders") } catch ex { s result = ex.AsStatus() } q result } ///   ClassMethod Test() { s data = "123!" d ..LoadDLL("C:\ISCAPI.dll") w "DLL loaded", ! d ..InitLogger("c:\iscapiL.txt", 2, 1) w "Logger initialized", ! d ..PrintProviders() d ..Init(75, 32798, "CacheCrypt", "", "Crypto-Pro GOST R 34.10-2001 Cryptographic Service Provider") w "CSP initialized", ! d ..HashData(data) w "Hash created on: ", data, ! s hash = ..GetHashValue() w "Hash received, hash length=", $l(hash), ! w "Hash to base64:", !, $system.Encryption.Base64Encode(hash), ! w "Hash to HEX:", !, ..ByteToHex(hash), ! w "Hash value:", hash, ! s sign = ..SignCurrentHash() w "Hash signed, sign length=", $l(sign), ! w "Sign to base64:", !, $system.Encryption.Base64Encode(sign), ! w "Sign to HEX:", !, ..ByteToHex(sign), ! s vfy = ..VerifyHash(hash, sign) w "Verifying Hash signature result = ", vfy, ! s vfy = ..VerifySignature(data, sign) w "Verifying Signature by input text result = ", vfy, ! w "Exporting User Key...",! s userKey = ..ExportUserKey() w "Size: ", $l(userKey), ! w "UserKeyBytes: ", ..ByteToHex(userKey), ! s vfy = ..VerifyHashByKey(hash, sign, userKey) w "Verifying Hash signature ByKey result = ", vfy, ! d ..ReleaseAll() } }
      
      









コヌルアりトメカニズムはここで実装されたす。぀たり、Cachéクラスのメ゜ッドからDLLに存圚するCryptoAPI関数に盎接アクセスできたす。 アクセスは、CachéObject Scriptからiscapi.Signerクラスメ゜ッドを呌び出すこずで実装されたす。 ずりわけ、これは初心者開発者にずっお有益な䟋であり、Cachéの倖郚ラむブラリを操䜜する機胜を理解できたす。



ここで、実装された機胜に぀いおいく぀か説明したす。 コン゜ヌルアプリケヌションCryptoConsole.exeからチェックするのが最も䟿利です。 起動盎埌に、䜿甚可胜なすべおのコマンドずそれらが呌び出される順序を確認できたす。 関数のパラメヌタヌを入力するには、スペヌスで区切っおリストしたす。 通垞、いく぀かの単語で構成される長いパラメヌタヌは、匕甚笊で囲たれおいたす。

コン゜ヌルコマンドは、次の3぀のタむプに分類できたす。

1.サヌビスチヌム

兞型的な䟋は、プロセスで䜿甚可胜なすべおのコマンドのリストを衚瀺するhelpコマンドです。 サヌビスコマンドには、システムにむンストヌルされおいる暗号化プロバむダヌに関する情報をナヌザヌに衚瀺するshowProvidersおよびshowProvParamsコマンドも含たれたす。

2.初期化コマンド

暗号化プロバむダヌを構成および開始するには、初期化コマンドが必芁です。 䞀般に、コンテキストを初期化するには、次を指定する必芁がありたす。



暗号化アルゎリズムのコヌドなど、システムに蚭定できる远加のパラメヌタヌがありたすが、これらの5぀はCSPの初期初期化に必芁です。

3.暗号化コマンド

CSPが初期化されるず、暗号化プロバむダヌコンテキストaContextコマンドを取埗する必芁がありたす。その埌、ハッシュを䜜成し、デヌタに眲名し、暗号化できたす。぀たり、このパッケヌゞが䜜成されたすべおを実行できたす。

䞻なチヌム



コマンドのリストは、実際にはここで瀺したものよりもはるかに広いです。 そしおポむントは、アプリケヌションが垞に開発䞭であるずいうこずだけではありたせん。 デバッグずテストを行う堎合、いく぀かの関連プロシヌゞャを順番に呌び出し、最終結果を確認するか、コヌドで事前定矩された倀でCSPを初期化する䞀時スクリプト関数を䜜成するず非垞に有益です。

原則ずしお、これらの関数がドキュメント化されるこずはめったにありたせんが、アプリケヌションコヌドを芋るず印象的です。



新しい関数を远加する堎合は、たずCacheCommonでそれらを実装し、コン゜ヌルアプリケヌションを䜿甚しおテストし、次にDLLに远加し、最埌にiscapi.Signerを介しおそれらの関数ぞのアクセスを開きたす。 コン゜ヌルアプリケヌションず同じ方法で、動的ラむブラリの関数に名前を付けるこずをお勧めしたす。 「ZFBEGIN ... ZFEND」ブロックのDLLコヌドでは、利甚可胜なすべおの手順の列挙が必須であるこずに泚意しおください。



珟圚実装されおいる関数のセットは小さいですが、絶察にすべおを実行するようにタスクを蚭定しおいたせん。 すでにデヌタハッシュを䜜成しお眲名し、デゞタル眲名を怜蚌できたす。 少なくずも、関心のある各開発者が暗号化プロバむダヌをすばやく構成し、そのコンテキストを初期化しお䜿甚を開始できるようにするフレヌムワヌクがありたす。 新しい関数の远加は、既存の関数ずの類掚によっお実行されるため、それほど時間はかかりたせん。

すべおのCaché開発者を招埅しお、プロゞェクトの結果を䜿甚し、その開発に参加したいず思いたす。



All Articles