Como fazer uma assinatura eletrônica você mesmo

Farei uma reserva imediatamente - sou quase um amador em assuntos relacionados à assinatura digital eletrônica (EDS). Recentemente, motivado pela curiosidade natural, decidi resolver um pouco isso e encontrei 100.500 artigos na Internet sobre o tema de obtenção de certificados de assinatura digital em vários centros de certificação, além de inúmeras instruções para o uso de vários aplicativos prontos para assinatura de documentos. Em alguns lugares, foi mencionado de passagem que uma assinatura não qualificada pode ser feita independentemente se você usar os serviços de um "programador experiente".


Eu também queria me tornar pelo menos um pouco "experiente" e entender essa cozinha por dentro. Por diversão, aprendi como gerar chaves PGP, assinar documentos com uma assinatura não qualificada e verificar sua autenticidade. Entendendo que nenhuma América está aberta, no entanto, ofereço este breve tutorial para amadores que são iguais a mim em questões de trabalho com assinaturas digitais. Tentei não particularmente me aprofundar na teoria e nos detalhes, mas escrever apenas uma pequena e breve introdução à questão. Para aqueles que já trabalham com a EDS, é improvável que seja interessante, mas para iniciantes, para o primeiro conhecido - exatamente o que é certo.


O que é uma assinatura eletrônica


Todos os termos e definições são dados na lei ; portanto, declararemos tudo, como dizem, em suas próprias palavras, sem pretender a precisão jurídica absoluta da redação.


Uma assinatura digital eletrônica (EDS) é uma coleção de ferramentas que permite verificar claramente se o autor de um documento (ou o executor de uma ação) é exatamente a pessoa que se autodenomina. Nesse sentido, a EDS é completamente análoga à assinatura tradicional: se o documento "papel" usual indica que seu autor é Ivanov, e a assinatura de Petrov está abaixo, você pode duvidar da autoria de 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;
}

Isso, de fato, é tudo. Agora, de acordo com a cláusula 5.23 do GOST 7.0.97–2016 , você pode colocar esta linda foto no documento (no local onde deve estar a assinatura manuscrita):



All Articles