Come descritto in RFC 5280 , un certificato ha la seguente struttura generale:
Certificate ::= SEQUENCE {
tbsCertificate TBSCertificate,
signatureAlgorithm AlgorithmIdentifier,
signatureValue BIT STRING }
I tre elementi sono "to-be-signed", un identificatore per l'algoritmo della firma e la firma. Se vuoi essere in grado di rigenerare lo stesso certificato, allora tutti e tre gli elementi devono essere ricostruiti in modo identico.
La maggior parte dei certificati in circolazione utilizza le firme RSA "v1.5", come descritto in PKCS # 1 . Questo algoritmo di firma è deterministico, quindi se si utilizza la stessa chiave privata, gli stessi parametri dell'algoritmo (la funzione hash compagna) e lo stesso input (il to-be-signed), si otterrà la stessa firma. Lo stesso NON vale per lo schema di firma "PSS" più recente e più elaborato descritto in PKCS # 1; quello è randomizzato e otterrai ogni volta un valore di firma diverso. Analogamente, se il tipo di chiave è DSA o ECDSA, lo schema di firma corrispondente è casuale, a meno che non si utilizzi una specifica implementazione deterministica . (che è possibile ma non un dato).
Supponendo di utilizzare uno schema di firma deterministico , la domanda si riduce alla riproduzione degli stessi contenuti da firmare. Il to-be-signed contiene quanto segue:
TBSCertificate ::= SEQUENCE {
version [0] EXPLICIT Version DEFAULT v1,
serialNumber CertificateSerialNumber,
signature AlgorithmIdentifier,
issuer Name,
validity Validity,
subject Name,
subjectPublicKeyInfo SubjectPublicKeyInfo,
issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
-- If present, version MUST be v2 or v3
subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
-- If present, version MUST be v2 or v3
extensions [3] EXPLICIT Extensions OPTIONAL
-- If present, version MUST be v3
}
La maggior parte delle librerie che creano "certificati autofirmati" introdurranno variazioni nel serialNumber
(poiché il numero seriale dovrebbe essere univoco, verrà generato in modo casuale) e validity
campi. Il validity
contiene le due date che delimitano l'intervallo di tempo della validità del certificato; in genere, una libreria che crea un certificato autofirmato utilizzerà la data e l'ora correnti per la prima data e, pertanto, non utilizzerà lo stesso valore se il certificato viene ricreato in un secondo momento.
Le estensioni sono, per definizione, aperte e possono contenere anche vari elementi casuali.
I certificati autofirmati , per definizione, NON sono certificati; vivono al di fuori del processo di convalida del certificato e tale processo è l'unico motivo per cui esistono effettivamente i certificati. Un certificato autofirmato è un nome e una chiave pubblica, codificati insieme in ciò che appare superficialmente come un certificato da una miscela di riutilizzo rapido e sporco del codice esistente, tradizione di lunga data e confusione storica. Tale "certificato" è autofirmato perché c'è un campo non facoltativo per una firma, ma quella firma non ha senso.
Pertanto, in un certificato autofirmato, la maggior parte se non tutte le "estensioni" saranno ignorate, così come altri campi come il numero di serie. Probabilmente (a seconda di ciò che il protocollo server-to-server richiede in questi "certificati"), riempire i campi con valori fissi fittizi che renderanno felice il tuo protocollo e potranno essere ricaricati identicamente in seguito. Tuttavia, non tutte le librerie di supporto esistenti lo consentiranno; potresti dover riscrivere il tuo codificatore di certificati (che è fattibile ma al prezzo della tua sanità mentale ).