Comment créer vous-même une signature électronique

Je ferai une réservation tout de suite - je suis presque un amateur en matière de signature numérique électronique (EDS). Récemment, poussé par la curiosité naturelle, j'ai décidé de trier un peu cela et j'ai trouvé 100500 articles sur Internet sur le thème de l'obtention de certificats de signature numérique dans divers centres de certification, ainsi que de nombreuses instructions pour l'utilisation de diverses applications prêtes à l'emploi pour la signature de documents. Dans certains endroits, il a été mentionné en passant qu'une signature non qualifiée peut être faite indépendamment si vous utilisez les services d'un "programmeur expérimenté".


Je voulais aussi devenir au moins un peu «expérimenté» et comprendre cette cuisine de l'intérieur. Pour le plaisir, j'ai appris à générer des clés PGP, à signer des documents avec une signature non qualifiée et à vérifier son authenticité. Comprenant qu'aucune Amérique n'est ouverte, je propose néanmoins ce petit tutoriel pour les amateurs qui sont les mêmes que moi en matière de travail avec EDS. Je n'ai pas essayé particulièrement de me plonger dans la théorie et les détails, mais d'écrire juste une petite et brève introduction à la question. Pour ceux qui travaillent déjà avec EDS, il est peu probable que cela soit intéressant, mais pour les débutants, pour la première connaissance - tout à fait.


Qu'est-ce qu'une signature électronique


Tous les termes et définitions sont donnés dans la loi , par conséquent, nous énoncerons tout, comme ils le disent, dans vos propres mots, sans prétendre à l'exactitude juridique absolue de la formulation.


Une signature numérique électronique (EDS) est un ensemble d'outils qui permettent de vérifier clairement que l'auteur d'un document (ou l'interprète d'une action) est exactement la personne qui se fait appeler l'auteur. En ce sens, l'EDS est complètement analogue à la signature traditionnelle: si le document «papier» habituel indique que son auteur est Ivanov et que la signature de Petrov est ci-dessous, vous pouvez à juste titre douter de la paternité d'Ivanov.


. ; ( ), — . , , , , , .


: ( , ). ( ) , . , : , fetch- ajax- . , : , .


. ; , , . - ( , , ), : . ; (public key), — (private key). , , .


, ( ? ) , , , . , , , . , , , .


, : , — . ( ) . , , , , - ! . ( ), , .


. , . : . ( ) . , , , , .


. (detach), . , - .


? : , . :


  • ;
  • , ;
  • , , ( ). !

, , , «». , . , , . : , . , ...


. , , , ( , ). ( ), . , , (fingerprint), , , . , , , , , . , ( 40 ).


, , , — , . . : , ( ). , , .


, (, ) , . , ( ): .


, : - (, ) . , , .


, ( ) ( ). , (, ). (, ) , , .



, . , , , (public key) (private key).


. , , PGP (Pretty Good Privacy). 1991 , (, OpenPGP). 1999 GNU Privacy Guard (GnuPG, GPG). GPG ; - Windows , , gpg4win. - .


, (- , - root')


gpg --full-generate-key

:


  • «RSA RSA ( )»;
  • , 2048 ;
  • « »;
  • , , , ; ;
  • , .

GPG , . , , , GPG . , , , .


( , , , , ) :


gpg --export -a "  " > public.key
gpg --export-secret-key -a "  " > private.key

, private.key , public.key .



, (ASCII) :


gpg -ba __

, asc. , , privet.doc, privet.doc.asc. , , privet.sig, .


, , , :


#!/usr/bin/python
# -*- coding: utf-8 -*-
from Tkinter import *
from tkFileDialog import *
import os, sys, tkMessageBox

def die(event):
    sys.exit(0)

root = Tk()
w = root.winfo_screenwidth()//2 - 400
h = root.winfo_screenheight()//2 - 300
root.geometry("800x600+{}+{}".format(w, h))
root.title(" ")

flName = askopenfilename(title=" ?")

if flName:
    os.system("gpg -ba " + flName)
    button = Button(text=" ")
    button.bind("<Button-1>", die)
    button.pack(expand=YES, anchor=CENTER)
else:
    die()

root.mainloop()


, , , ( ) , :


gpg --verify __ __

- (, ):


  • public.key , () , , GPG;
  • - , .

- ( , ) .


, OpenPGP.js; ( — 506 ) dist/lightweight/openpgp.min.js html- ( meta-):


<!DOCTYPE html>
<html>
<head><meta charset="utf-8"></head>
<body>

<label for="doc">   </label>
<input id="doc" type="file" onChange="readDoc('doc')">

<label for="sig">   </label>
<input id="sig" type="file" onChange="readDoc('sig')">

<button type="button" disabled onClick="check()"></button>
<output></output>

<script src="openpgp.min.js"></script>
<script src="validate.js"></script>

</body>
</html>

, public.key openpgp.min.js , .


validate.js:


"use strict";
let cont   = {doc:'', sig:''},
    flag   = {doc:false, sig:false},
    pubkey = '',
    mess   = '';

//    ( ),
//    ( )
const readDoc = contKey => {
    let reader = new FileReader();
    reader.onload  = async e => {
        cont[contKey] = contKey == "sig" ?
                        e.target.result :
                        new Uint8Array(e.target.result);
        flag[contKey] = true;
        pubkey = await (await fetch("public.key")).text();   
        if (flag["doc"] && flag["sig"])
            document.querySelector("button").disabled = false;
    }
    reader.onerror = err => alert("  ");

    let fileObj = document.querySelector(`#${contKey}`).files[0];
    if (contKey == "sig") reader.readAsText(fileObj);
    else                  reader.readAsArrayBuffer(fileObj);
}

//  
const check = async () => {
    try {   
       const verified = await openpgp.verify({
           message:    openpgp.message.fromBinary(cont["doc"]),
           signature:  await openpgp.signature.readArmored(cont["sig"]),
           publicKeys: (await openpgp.key.readArmored(pubkey)).keys
       });
       const {valid} = verified.signatures[0];
       mess = "    !";
       if (valid) mess = "   .";
    } catch(e) {mess = "    .";}
    document.querySelector("output").innerHTML = mess;
}

En fait, c'est tout. Maintenant, conformément à la clause 5.23 de GOST 7.0.97-2016 , vous pouvez placer cette belle image sur le document (à l'endroit où devrait se trouver la signature manuscrite):



All Articles