4D Write Pro – Firma y protege documentos

Traducido automáticamente de Deepl

El propósito de este artículo es mostrar cómo, de una manera fácil de implementar, se pueden firmar y verificar documentos de forma transparente.
El beneficio obvio de este enfoque es la tranquilidad cuando los documentos se abren de nuevo, con la certeza de que no han sido modificados en el ínterin.

Esto es especialmente importante si almacena documentos 4D Write Pro como plantillas inteligentes que contienen código 4D como archivos externos en el disco. Antes de ejecutar este código querrá asegurarse de que el archivo no ha sido modificado externamente.

O, en el caso de documentos externos, estar seguro de que provienen del remitente correcto y no han sido alterados durante su viaje digital.
El principio que vamos a describir se aplica a los documentos 4D Write Pro, pero vale para cualquier otro tipo de documento con algunas pequeñas modificaciones.

Ejemplo de base de datos

¿Encriptación o firma?

Aquí vamos a concentrarnos en la autenticación de un documento, es decir, cómo estar seguros de que no ha sido modificado entre el momento en que fue registrado por su propietario original (legal/oficial/etc.) y el momento en que es leído por su destinatario (¡o releído por su propietario!). No estamos hablando de encriptación, aunque también puede hacerse, pero ese es otro tema. (Si te interesa la criptografía, consulta este BLOG)

Crear una firma.

El proceso de creación de una firma es bastante sencillo: a partir del documento original creamos una firma basada en el documento completo (como un BLOB) utilizando una clave «privada». Esta firma (y sólo esta firma) se almacenará en el propio documento, normalmente al final del mismo.

Releer la firma

Antes de abrir el documento, se relee la firma oficial. Se creará un nuevo BLOB a partir del documento completo (sin la clave final, por lo que teóricamente será idéntico al original) y se verificará, esta vez utilizando una clave pública, íntimamente ligada a la clave privada que se ha utilizado para crear la firma. El resultado de esta verificación determinará lo que ocurrirá a continuación.

En esta fase, existen tres posibilidades…

Hemos supuesto que el documento está firmado, pero no es necesariamente así. Si el documento no contiene firma, se impone la prudencia, aunque no está necesariamente viciado.
Abrir o no el documento depende del desarrollador, del usuario, de las circunstancias, del entorno… En resumen, ¡hay que decidir qué hacer!

La segunda posibilidad es que la firma corresponda al contenido. Buenas noticias entonces. Puedes estar seguro de que el documento es el que tú creaste o el que se te confió/envió/etc., y sobre todo de que no ha sido alterado desde su creación. Esto significa que puede abrirlo con total tranquilidad, siempre que confíe en el remitente. A continuación, es libre de modificarlo, guardarlo, volver a firmarlo o no, en función de su uso futuro. Si necesita modificarlo y enviarlo de nuevo al remitente, es conveniente que lo firme usted mismo, para que el futuro destinatario pueda realizar la misma operación.

Por último, la tercera posibilidad es que el documento haya sido alterado (o incluso corrompido) durante la transferencia. La más mínima coma añadida o suprimida, la más mínima fórmula modificada, etc. ¡significará que la firma ya no coincide!
Lo sabrá inmediatamente, para poder tomar las medidas oportunas.

Pongámonos manos a la obra.

En este ejemplo, vamos a firmar uno o varios archivos existentes ya guardados en formato 4D Write Pro, es decir, con extensión . «4wp». Como vamos a gestionar ficheros, utilizaremos las clases 4D.File y 4D.FileHandle. Y como vamos a gestionar claves de encriptación, firma y verificación, también usaremos 4D.CryptoKey (vea el BLOG correspondiente si aún no está familiarizado con estas clases…).

SAFE Crear Claves por Defecto

En primer lugar, crearemos un par de claves privadas/públicas y las almacenaremos de una vez por todas como una entidad en la base de datos (Este par de claves se utilizará como claves «por defecto» más adelante, a modo de ejemplo).

$cryptoKey:=ds.CryptoKey.new()
$keyOptions:={type: "RSA"; size: 2048}
$key:=4D.CryptoKey.new($keyOptions)

$cryptoKey.privateKey:=$key.getPrivateKey()
$cryptoKey.publicKey:=$key.getPublicKey()

$cryptoKey.save()

Firma SAFE del documento

A continuación, es necesario añadir una firma al final de un fichero (4D.File) utilizando una clave privada.
En resumen, esto es lo que tiene que hacer:

// create a new key based on private key
$keyOptions:={type: "PEM"; pem: $privateKey}
$key:=4D.CryptoKey.new($keyOptions)

//…
// create the signature with the .sign() function
$signOptions:={hash: "SHA512"; encodingEncrypted: "Base64URL"}
$signature:=$key.sign($documentAsBlob; $signOptions)

// append signature (as a BLOB) at the end of the document
TEXT TO BLOB($signature; $blobSignature; UTF8 text without length)
$fileHandle.offset:=$documentSize
$fileHandle.writeBlob($blobSignature)

SAFE Comprobar firma

Por último, ANTES de abrir el documento, debe comprobar su firma. Esto se hace mediante el siguiente método, al que se le pasa un fichero (4D.File) y, opcionalmente, una clave pública

// create a new key based on public key
$signOptions:={hash: "SHA512"; encodingEncrypted: "Base64URL"}
$type:={Type; "PEM"; pem; $publicKey}
$key:=4D.CryptoKey.new($type)

// read the real signature 	
//…
$fileHandle.offset:=$documentSize-$length
$blobSignature:=$fileHandle.readBlob($length)
$textSignature:=BLOB to text($blobSignature; UTF8 text without length)

// check the signature using the .verify() function
$check:=$key.verify($documentAsBlob; $signature; $signOptions)
If ($check.success)
	$result:=1
Else 
	$result:=-1
End if 

Esto funciona con .4wp, pero ¿qué pasa con otros documentos?

Cuando 4D Write Pro carga un documento .4wp, se detecta automáticamente el final del documento para saber dónde parar. La firma añadida al final del archivo no lo interrumpe. En otras palabras, tanto si el documento está firmado como si no, tanto si la firma es correcta como si no, el .4wp se cargará sin ningún problema, de ahí la necesidad de comprobar previamente su firma.

Para otros tipos de documentos, es posible (incluso probable) que añadir una firma al final interrumpa la carga, por lo que puede ser necesario -después de validarlo, por supuesto- eliminar la firma.

Documento SAFE Unsign

Por esta razón, se ha creado este otro método para realizar la operación contraria.
Elimina la firma de un documento para devolverlo a su estado original, y si el documento no está firmado, simplemente no hace nada.

$fileHandle:=$file.open("write")  
//…  calculate signature length then…
$fileHandle.setSize($documentSize-$length)

Conclusión

Este sencillo ejemplo muestra cómo firmar un documento y verificar la firma antes de abrirlo. Cuando se intercambian documentos entre dos sitios, se necesitan dos pares de claves públicas/privadas, pero el principio sigue siendo el mismo. El creador del documento firma con una clave privada, y el lector lo verifica con la clave pública suministrada por el creador.
Las claves pública y privada son activos valiosos que permiten tanto la firma como la autenticación, por lo que es aconsejable guardarlas en el propio archivo de datos.

Roland Lannuzel
- Propietario de Producto y Experto en 4D - Después de estudiar electrónica, Roland se dedicó a la informática industrial como desarrollador y consultor, construyendo soluciones para clientes con una variedad de bases de datos y tecnologías. A finales de los años 80 se enamoró de 4D y lo ha utilizado para escribir aplicaciones de negocio que incluyen sistemas de contabilidad, facturación y correo electrónico.Eventualmente se unió a la compañía en 1997, las valiosas contribuciones de Roland incluyen el diseño de especificaciones, herramientas de prueba, demos, así como la formación y hablar con la comunidad 4D en muchas conferencias. Continúa dando forma activamente al futuro de 4D definiendo nuevas características y herramientas de desarrollo de bases de datos.