Delphi-Quellcode:
procedure Encode(var Value: TLicenseBlock);
begin
with TCipher_Rindael.Create do
try
Mode := cmCFS8;
Init(Key);
Encode(Value, Value, SizeOf(Value));
finally
Free;
end;
end;
Das ist der einfachste Weg. Wichtig in deinem Falle ist der Cipher.Mode cmCFS8. Du kannst cmCFB8, cmOFB8, cmCFS8 benutzen. Diese Modis arbeiten auf 8Bit = 1 Byte und verschlüsseln somit einen Datenblock häufiger als die anderen Cipher Modis. Gerade bei kurzen und sehr sicherheits relevanten Daten wie Lizenzschlüsseln, Passwörtern sollte man diese Modis benutzen.
Ich empfehle dir jetzt noch ein par Änderungen an deinem TLicenseBlock:
Delphi-Quellcode:
TLicenseBlock = packed record
RandomSalt: array[0..15] of Byte; // <- Zufallsdaten
Code : TCode;
ApplicationKey : TKey;
Modifier : LongInt;
LicVersionLow : word;
LicVersionMid : word;
LicVersionHigh : word;
LicVersionStr : TLicenseString;
RegUserName : TLicenseString;
RegCompany : TLicenseString;
VendorName : TLicenseString;
VendorCompany : TLicenseString;
end;
TLicenseData = packed record
PasswordSalt: array[0..15] of Byte; // Zufallssalt fürs Password
Data: TLicenseBlock;
end;
uses DECRandom;
procedure Encode(var Value: TLicenseData);
begin
RandomBuffer(Value.PasswordSalt, SizeOf(Value.PasswordSalt));
RandomBuffer(Value.Data.RandomSalt, SizeOf(Value.Data.RandomSalt));
with TCipher_Rindael.Create do
try
Mode := cmCFS8;
Init(THash_SHA1.KDFx(Key, SizeOf(Key), Value.PasswordSalt, SizeOf(Value.PasswordSalt), Cipher.Context.KeySize, TFormat_COPY));
Encode(Value.Data, Value.Data, SizeOf(Value.Data));
finally
Free;
end;
end;
Mit diesen beiden Änderungen werden effektiv mindestens 2 Angriffe verhindert oder erschwert
1.) Brute Force Attacke auf das Password -> Key. Ein Angreifer kann nun nicht mehr zb. durch Rainbow Tabellen eine effiziente Wörterbuchattacke auf das Password durchführen. Er ist gezwungen eine echte langwierige Brute Force Attacke durchzuführen. Wir schützen also das verwendete Password.
2.) mit den 16 Bytes RandomSalt in deinem Lizenz Block, die ja mit verschlüsselt werden, wird eine Known Plain Text Attacke erschwert bzw. verhindert. Ein Angreifer kann also nicht mehr auf Grund das er den Aufbau deiner Lizenzdaten kennt einen verschl. Lizenzblock knacken. Ohne diese Erweiterung kann er davon ausgehen das zb. im 1 Byte -> Code: TCode nur ganz bestimmte Werte drinnen stehen können. Diese Information würde es ihm ermöglichen seine "Brute Force" Testentschl. zu verifizieren. Mit dem vorgesetzten RandomSalt ist dies nun ausgeschlossen, bzw. die Komplexität dieses Test erhöht sich von 1 zu 1 auf 1 zu 2^(16 * 8 ).
3.) durch einbinden der
Unit DECRandom wird ein sogennater YARROW Random Generator eingebunden. Wenn du diesen per RandomSeed(DeineDaten) sicher initialisierst (also nicht reroduzierbar für einen Angreifer) dann ist der Zufallsstrom dieses Generator nicht knackbar (zumindestens nicht so lange SHA1 als Hashfunktion nicht geknackt wurde).
Alle Random?????() Funktion in DECUtils benutzten nach dem Einbinden von DECRanndom() diesen YARROW RNG. Ohne diese
Unit wird ein Borland-ähnlicher simpler LCG RNG benutzt, der natürlich unsicher ist.
Mit diesen drei simplen Änderungen kann ich dir garantieren das nur noch eine Brute Force Attacke, also das Durchprobieren aller Schlüssel, der Datenblock zu knacken geht. Alle effizienteren Verfahren sind ausgeschlossen, unter den Annahmen
1.) der Cipher ist sicher -> AES Rijndael
2.) die Hashfunktion ist sicher -> SHA1
3.) die Zufallsfunktion ist sicher -> SHA1 YARROW von Bruce Schneier
4.) das Passwort Key ist sicher -> also im Hirn gespeichert und nicht in der EXE
Da es sich bei diesem Verfahren um eine symmetrische Verschlüsselung handelt hast du das Problem an Punkt 4.) mit dem Schlüsselaustausch. Wenn du das nicht sicher gelösst bekommst ist das ganze Verfahren immer knackbar. Dh. der Angrefer kann immer das Passwort zb. durch Spyware in Erfahrung bringen. Die einzigste Lösung für dieses Problem sind die asymmetrischen Verfahren, genauergesagt die "digitalen Signaturen". Bei diesen Verfahren gibt es 2 getrennte "Operatonen". Einmal die Erzeugung einer digitalen Signatur die einen privaten Schlüssel benötigt. Dieser liegt natürlich nur auf deinem Server und niemals bei deinen Kunden. Die zweite Operation ist die Verifikation einer solchen Signatur. Diese Operation kommt OHNE den privaten Schlüssel aus und wird somit in deine Software zur Verifikation der Lizenz benutzt. Ein Key Generator ist somit ausgeschlossen, wenn wir davon ausgehen können das ein Angreifer NICHT deinen Public Key in deiner EXE austauschen kann.
Fazit: ohne die Grundbedingung das deine EXE in einem sicheren Kontext ausgeführt wird wirst du niemals eine sichere Lizenz hinbekommen !
Gruß Hagen