
Digitale Signaturen kommen in vielen Gebieten, in denen Authentizität und Integrität eine wichtige Rolle spielen zum Einsatz. Beispiele sind E-Mails, Rechnungen oder elektronische Ausweise. Im Zuge dessen wird es in der kommenden CONZEPT 16-Version 5.7.08 möglich sein, digitale Signaturen zu erstellen und zu verifizieren.
Allgemeines
Eine digitale Signatur ist eine elektronische Sicherheitskennzeichnung, mit der sichergestellt werden soll, dass eine Nachricht tatsächlich vom angegebenen Absender stammt und dass der Inhalt seit dem Erstellen der Signatur nicht verändert wurde.
Die Erstellung einer Signatur verwendet ein asymmetrisches Kryptoverfahren, bei dem zunächst der Hash-Wert der zu übermittelnden Nachricht berechnet wird. Dieser Hash-Wert wird anschließend mit einem privaten Schlüssel verschlüsselt und das Ergebnis an die Nachricht angehängt.
Der Empfänger der Nachricht kann die Signatur mit dem zugehörigen öffentlichen Schlüssel verifizieren. Dazu wird aus der Nachricht erneut der Hash-Wert berechnet. Anschließend wird der angehängte, verschlüsselte Hash-Wert mit dem öffentlichen Schlüssel des Absenders entschlüsselt. Stimmen die beiden ermittelten Hash-Werte überein, lässt sich daraus schließen, dass der Absender korrekt ist und die Nachricht nicht von Dritten verändert wurde.
Das ganze System setzt allerdings voraus, dass ausschließlich die autorisierten Signatur-Ersteller im Besitz des privaten Schlüssels sind. Eine klare Zuordnung des privaten Schlüssels zu einer Person kann beispielsweise durch ein Zertifikat geschehen.
Die Ver- und Entschlüsselung von Signaturen kann in CONZEPT 16 mit den beiden asymmetrischen Verfahren RSA oder DSA erfolgen. Für die Hash-Werte sind die Methoden MD5, Ripe-MD, SHA-1 und SHA-2 verfügbar.
Signatur erzeugen
Der Befehl zum Signieren lautet MemSign()
und ist wie folgt definiert:
MemSign(
aMem : handle // Memory-Objekt mit Nachricht
aOptions : int // Optionen
aKey : alpha // Privater Schlüssel
vSignature : alpha // Out:Signatur
opt aPos : int // Nachrichtenposition im Memory-Objekt
opt aLen : int // Länge der Nachricht im Memory-Objekt
)
: int // Fehlerwert
In aMem
wird ein Memory-Objekt übergeben, welches die zu signierende Nachricht enthält.
In aOptions
erfolgt die Auswahl der Algorithmen für die vier Bereiche Signatur-Algorithmus, Hash-Algorithmus, Kodierung des privaten Schlüssels und die Kodierung der Signatur.
- Signatur-Algorithmus
_MemSignRSA
,_MemSignDSA
- Hash-Algorithmus
_MemHashMD5
,_MemHashRMD160
,_MemHashSHA1
,_MemHashSHA256
,_MemHashSHA384
,_MemHashSHA512
- Schlüsselkodierung
_MemKeyHex
,_MemKeyBase64
- Signaturkodierung
_MemResultHex
,_MemResultBase64
In aKey
wird der private Schlüssel übergeben. Dieser kann in den Formaten PKCS #1 oder PKCS #8 vorliegen.
vSignature
ist ein Referenzargument und enthält beim erfolgreichen Signieren die Signatur, andernfalls einen Leerstring.
Die Argumente aPos
und aLen
sind optional und werden dazu verwendet, den Bereich im Memory-Objekt anzugeben, der die zu signierende Nachricht enthält.
War das Signieren erfolgreich, liefert die Funktion MemSign()
_ErrOK
zurück. Andernfalls kann einer der folgenden Fehlerwerte zurückgegegeben werden:
_ErrMemKeyInvalid
Der Fehler tritt auf, wenn zum Beispiel ein RSA-Key erwartet wird, jedoch ein anderer (ungültiger) Key angegeben wurde, oder wenn die Dekodierung des Schlüssels fehlschlug._ErrMemKeyLength
Der angegebene Schlüssel ist zu kurz, um die Nachricht zu signieren.
Mit folgendem Beispiel kann eine Signatur erzeugt werden:
// ...
tErg # tMem->MemSign(
_MemSignDSA | // Es soll eine DSA-Signatur erzeugt werden
_MemHashSHA1 | // SHA1-Hash
_MemKeyBase64 | // Key ist Base64-Kodiert
_MemResultBase64 | // Signatur wird Base64-Kodiert
tPrivateKey, // Privater Schlüssel
var tSignature, // Signatur wird in tSignature abgelegt
);
// Signatur ausgeben
WinDialogBox(0, 'Signatur', tSignature, _WinIcoInformation, _WinDialogOk, 0);
// ...
Signatur verifizieren
Der Befehl MemVerify()
hat ebenfalls 6 Parameter,
MemVerify(
aMem : handle // Memory-Objekt mit Nachricht
aOptions : int // Optionen
aKey : alpha // Öffentlicher Schlüssel
aSignature : alpha // Signatur, die verifziert werden soll
opt aPos : int // NAchrichtenpoistion im Memory-Objekt
opt aLen : int // Länge der Nachricht im Memory-Objekt
)
: int // Fehlerwert
die sich in drei Punkten zu MemSign()
unterscheiden:
aOptions
definiert die Kodierung der angegebenen Signatur mit den Konstanten_MemSignatureHex
oder_MemSignatureBase64
.aKey
beinhaltet den öffentlichen Schlüssel im X509-Format. RSA-Schlüssel können auch im Format PKCS #1 angegeben werden.- In
aSignature
wird die zu verifizierende Signatur übergeben.
War die Verifizierung erfolgreich, gibt die Funktion MemVerify()
_ErrOK
zurück. Andernfalls wird eine der folgenden Werte zurückgegeben:
_ErrMemMsgVerify
Die Signatur passt nicht zum Schlüssel._ErrMemSgnInvalid
Das Dekodieren der Signatur schlug fehl oder die Signatur ist ungültig._ErrMemKeyInvalid
Das Dekodieren des Schlüssels schlug fehl oder der Schlüssel ist ungültig.
Ein Beispiel zur Verifikaiton:
// ...
tErr # tMem->MemVerify(
_MemSignDSA | // DSA-Signatur liegt vor
_MemHashSHA1 | // SHA1-Hash muss verwendet werden, da Signatur mit SHA1 erzeugt wurde
_MemKeyBase64 | // Key ist Base64-Kodiert
_MemSignatureBase64, // Signature ist Base64-Kodiert
tPublicKey, // öffentlicher Schlüssel
tSignature // Signatur
);
if (tErr = _ErrOK)
WinDialogBox(0, 'Verifizierung', 'Die Signatur wurde verifiziert.', _WinIcoInformation, _WinDialogOk, 0);
// ...
Zusätzlich zu den Fehlerwerten, können beide Funktionen die Laufzeitfehler _ErrHdlInvalid
, _ErrValueInvalid
und _ErrValueRange
auslösen.
6 Antworten
@gkoinzer
Eine sogenannte Zertifizierungsstelle (certification authority) nimmt das Erstellen und die Ausgabe von digitalen Zertifikaten vor. Zertifikatsaussteller haben unterschiedliche Preismodelle. Die Kosten hängen von der Art des Zertifikats (Serverzertifikat, E-Mail-Signatur etc.), sowie von der Anzahl der benötigten Zertifikate ab.
Bitte für den bezüglich Zertifikaten unwissenden Nutzer noch ein paar Hinweise über Zertifikate:
– wo am besten ausstellen lassen
– Kosten
– was ist zu beachten bzw. wo liegen Risiken
– wie sollte der Ablauf organisiert bzw. automatisiert werden
Ja, das ist natürlich ein berechtigter Punkt. Danke für die Klarstellung.
@Kilian
Für die Überprüfung älterer Signaturen ist MD5 auf jeden Fall notwendig, für die Generierung neuer Signaturen sollte es nach Möglichkeit nicht mehr verwendet werden. Leider läßt sich der Fall, das andere (ältere) Software-Anwendungen Signaturen mit MD5 erwarten, nicht zu 100% ausschließen, daher gibt es eben noch diese Option für MemSign().
Vielen Dank für Ihre Rückmeldung.
Die Erweiterung des kryptografischen Bereichs in CONZEPT 16 ist hiermit noch nicht abgeschlossen. Wünsche und Anregungen von unseren Softwarepartnern sind natürlich für zukünftige Erweiterungen gern gesehen.
Super, das ist m. E. eine gute Erweiterung, die sicherlich sehr hilfreich sein wird, um das keineswegs einfache Thema der Authentizität und Integrität von Informationen in den eigenen Anwendungen in den Griff zu bekommen!
Hier noch ein paar Anregungen:
– die Verwendung von MD5 ist problematisch, da MD5 bewiesenermassen nicht kollisionssicher ist, klar kann man auf einen anderen Hash-Algorithmus ausweichen, aber m. E. sollte MD5 gar nicht erst angeboten werden
– es ist super, dass es jetzt neben MemHash, und MemHMAC eine weitere kryptographische Funktion für Memory-Objekte gibt, was ich nach wie vor vermisse sind symmetrische Basisfunktionen wie AES und 3DES, also z.B. einen MemCrypt-Befehl mit entsprechenden Optionen _MemCryptAES128 usw.
– ähnlich wie nun neu die highlevel-Funktion MemSign könnte es später im Bereich der symmetrischen Verschlüsselung neben Basis-Funktionen wie AES und 3DES ebenfalls highlevel Funktionen für die authentifizierte Verschlüsselung (GCM, CCM, EAX usw.) geben