Atelier è il gestionale che ho costruito per i proprietari privati che affittano casa. Il cuore è il fascicolo di ogni contratto, e dentro il fascicolo c’è la firma. Questo articolo racconta come l’ho progettata, cosa registra davvero e, soprattutto, cosa non promette.

Il problema

Un contratto d’affitto tra privati spesso circola come PDF su WhatsApp, con una firma scansionata e nessuna traccia di chi ha firmato cosa, quando e con quale testo. Se nasce una discussione, ricostruire «com’era il contratto al momento della firma» diventa difficile.

Volevo un modo semplice per fissare tre cose: il testo, chi ha firmato e quando.

Cosa registra la firma

La firma in Atelier è una firma elettronica semplice. Quando una parte firma, salvo:

  • nome e cognome digitati dal firmatario;
  • data e ora, mostrate nel fuso Europe/Rome;
  • indirizzo IP;
  • dispositivo (lo user agent del browser).

Il contratto diventa attivo solo quando hanno firmato entrambe le parti, in qualunque ordine.

L’impronta SHA-256

All’attivazione genero il PDF del contratto firmato e calcolo un’impronta SHA-256 su testo del contratto e dati delle due firme. In forma semplificata:

import { createHash } from 'node:crypto'

function fingerprint({ leaseId, text, owner, tenant }) {
  const sig = (s) => ({
    fullName: s.fullName,
    signedAt: s.signedAt,
    ip: s.ip ?? null,
    userAgent: s.userAgent ?? null,
  })
  return createHash('sha256')
    .update(JSON.stringify({ leaseId, text, owner: sig(owner), tenant: sig(tenant) }))
    .digest('hex')
}

Due dettagli contano più dell’algoritmo:

  1. L’ordine delle chiavi è fisso. Costruisco l’oggetto campo per campo prima di serializzarlo: se l’ordine cambiasse, lo stesso contenuto produrrebbe un’impronta diversa.
  2. Gli stessi dati danno sempre la stessa impronta. Ho scritto test che verificano che l’impronta sia deterministica e che cambi se cambia anche solo il testo o un dato di una firma.

L’impronta compare nel PDF, insieme a una frase che dice cosa è stato calcolato e a cosa serve: verificare che il contenuto non sia stato alterato dopo la sottoscrizione.

Un chiarimento importante: l’impronta non è una firma crittografica. Chi ha il documento può ricalcolarla. Serve a verificare che il PDF corrisponda al testo e alle firme che il sistema conserva, non a dimostrare chi lo abbia prodotto.

Il PDF resta com’era alla firma

Il PDF viene generato una sola volta, quando il contratto diventa attivo, e poi non viene rigenerato. Se in seguito il canone cambia (per esempio per un adeguamento ISTAT), il documento firmato non cambia: l’impronta deve descrivere il contratto com’era, non com’è diventato.

Due firme quasi simultanee

Un bug che avrei potuto non vedere mai: se proprietario e inquilino firmano nello stesso istante, una lettura-modifica-scrittura ingenua può far sì che una firma cancelli l’altra. Per questo la firma avviene dentro una transazione sul documento aggiornato, e una firma già apposta non si sovrascrive mai: un secondo tentativo riceve un errore 409 e l’originale, con il suo timestamp e il suo IP, resta intatto.

Cosa la firma non è

Questa è la parte a cui tengo di più. Una firma elettronica semplice, ai sensi dell’art. 20 del Codice dell’Amministrazione Digitale, ha un valore probatorio liberamente valutabile in giudizio: non equivale a una firma digitale qualificata. Lo scrivo nel PDF stesso, e Atelier dichiara cosa non è anche nella pagina «Chi siamo».

Per questo Atelier non si presenta come fornitore di firma qualificata e, per i fascicoli gestiti da un’agenzia, la firma avviene fuori dall’app. È una scelta legale prima che tecnica, e la lettura che ne do è mia: non è consulenza legale, e per un caso concreto serve un professionista.

Cosa ho imparato

  • Un’impronta è utile solo se sai esattamente cosa hai messo dentro e lo dichiari.
  • I test sulla concorrenza (due firme insieme) valgono più di quelli sul percorso felice.
  • Dichiarare i limiti di un prodotto crea fiducia, non danno.