Laden...
V
vstm
myCSharp.de - Member
0
Themen
8
Beiträge
Letzte Aktivität
vor 7 Jahren
Dabei seit
16.03.2009
Alter
41
Beruf
Witzbold
Herkunft
Zürcher Oberland
Website
Erstellt vor 14 Jahren

Hallo

Naja das IST der Private Key (gut, jetzt ist er nicht mehr ganz so private).

Aber dies ist genau die Private-Key Struktur definiert in PKCS#1/asn. Jeder INTEGER aus der dumpasn1-Ausgabe entspricht einem INTEGER in dieser Struktur. Die Version ist also "0", der Exponent ist 65537 usw.


RSAPrivateKey ::= SEQUENCE {
version Version,
modulus INTEGER, -- n .NET: Modulus
publicExponent INTEGER, -- e .NET: Exponent
privateExponent INTEGER, -- d .NET: D
prime1 INTEGER, -- p .NET: P
prime2 INTEGER, -- q .NET: Q
exponent1 INTEGER, -- d mod (p-1) .NET: DP
exponent2 INTEGER, -- d mod (q-1) .NET: DQ
coefficient INTEGER, -- (inverse of q) mod p .NET: InverseQ
otherPrimeInfos OtherPrimeInfos OPTIONAL
}

habe noch die Namen welche .NET verwendet eingefügt. Diese (BIG)INTEGER-Zahlen sind die Zahlen welche bei der RSA-Berechnung zum Einsatz kommen. Die Komponenten Modulus und Exponent bilden den Public-Key während, D, P und Q den Private-Key bilden. Die "DP", "DQ" und "InverseQ" Komponenten sind vorberechnete Faktoren welche das durchführen der RSA-Berechnung erleichtern/beschleunigen sollen.

Wie auch immer die Integer-Werte solltest Du jetzt umwandeln können, das heisst entweder Du verwendest einen ASN1-Parser um den Key selber zu zerpflücken und in eine RSAParameter Struktur abzufüllen. Möglichkeit zwei: Du dumpst die Integer-Werte als Text raus (bzw. kopierst einfach das was das ASN1-Tool ausgibt in ein Textfile). Das heisst in diesem Moment hast Du von jeder Komponente eine Lange Hexadezimalzahl. Diese kannst Du dann eigentlich umwandeln in so ein XML-File mit etwa folgenden Schritten (Braucht .NET 4.0 wegen BigInteger, ausserdem musst Du eine Referenz zu System.Numerics hinzufügen. Dieser Code wird aber nur gebraucht um das XML zu erstellen und muss nicht zwingend im Schlussendlichen Projekt sein):


StringBuilder xmlStr = new StringBuilder();
xmlStr.Append("<RSAKeyValue>")
BigInteger modulus = BigInteger.Parse("00A9608334...", NumberStyles.AllowHexSpecifier);
xmlStr.Append("<Modulus>");
xmlStr.Append(Convert.ToBase64String(modulus.ToArray()));
xmlStr.Append("</Modulus>");
//dasselbe für Exponent bis InverseQ
xmlStr.Append("</RSAKeyValue>")

Kommt halt drauf was Dir besser geht. Die erstere Lösung ist sicher eleganter während die Zweite keine grosse Einarbeitung in das ASN1-Zeugs verlangt.

Ich bin mir aber nicht sicher ob, selbst wenn die XML-Datei schlussendlich korrekt aufgebaut ist, dass die MS-RSA-Crypto Implementation das ganze auch frisst. Habe privat angefangen SILC (Eine Art IRC mit Verschlüsselung) in .NET zu implementieren und hatte da etwas mühe, Private Keys von anderen Quellen zu importieren (konkret war es ein Public-Key welchen ich mit Googles Go erstellt hab... zugegeben, kein alltägliches Szenario). Ausserdem hatte ich mühe mit den Signaturen welche PKCS1SignatureFormat ausgegeben hat. Mangels Sourcecode der .NET-Lib (VS2010 Express) und Geduld hab ich RSA dann selber implementiert, erst dann hat der SILC-Server meine Signaturen gefressen. Kurz: die Arbeit mit der MS-Crypto API hatte bei mir eher eine Lebenszeitverkürzende Wirkung.

Hoffe das hilft etwas, mein Geschwafel tendiert sonst dazu mehr Verwirrung als Klarheit zu stiften 😉

Gruss Stefan

Erstellt vor 14 Jahren

Hallo

Kommt halt darauf an wie der Private-Key codiert ist, es gibt diverse verfahren welche nicht zwingenderweise Standardisiert sein müssen.

Das heisst Du musst zuerst mal herausfinden wie der Private-Key codiert ist. Irgendwie hab ich stark das Gefühl das dies ein DER-Codierter Public Key, wie er von openssl verwendet wird, ist.

Ich würde mal das openssl-Binary runterladen (wenn du eine Linux-Kiste hast wirst du openssl ziemlich sicher schon drauf haben) und folgendes in einer Cmd-Line versuchen:

openssl enc -base64 -A -d -in dealerPrivate.key | openssl rsa -noout -check -inform DER

Wenn er "RSA key ok" ausgibt, bist Du im Geschäft, dann kannst du "-check" mit "-text" auswechseln und so die Private-Key komponenten rausfinden. Diese liegen dann natürlich als eine Folge von Hex-Digits vor, welche Zuerst umgewandelt werden müssen in das Format welches im XML benötigt wird. An diesem Punkt wäre die Alternative höchstens das Du das Format selber implementierst und den Key so einlesen würdest.

Wenn er statt "RSA key ok" was anderes ausgibt hast Du ein Prob. Evtl ist es auch PKCS#8 oder PKCS#12 codiert.

Im .x509 findest Du nur die Public-Key Komponenten. Ein Zertifikat ist eigentlich nichts anderes als ein Public-Key welcher von einer CA signiert ist (sofern nicht Selbstsigniert) und noch ein paar Informationen über den Besitzer des Public-Keys enthält.

Erstellt vor 15 Jahren

Hallo Zusammen

Laut Doku geht hier schon alles mit rechten Dingen zu. lock() verwendet ja intern einen Monitor. Und in der Monitor.Enter doku steht:

Derselbe Thread kann Enter mehrmals ausführen, ohne dass er blockiert wird.

Ich denke da musst du zusätzlich noch einen boolean nehmen um deinen Fall abzudecken.

Mfg Stefan

Erstellt vor 15 Jahren

Hi

Naja Du kanst den Term mal 10 nehmen. Also so: (26 * m - 2) / 10. Aber ich verstehe nicht warum Du int verwenden wilst. Wenn Du Convert.ToInt32(Math.Floor(2.6 * m - 0.2)) nimmst kommts ja auf das selbe raus.

Mfg Stefan

Erstellt vor 15 Jahren

Hi


retval = GetPrivateProfileString(null, null, "leer", sb, sb.Capacity, path);
sb.Length = retval; // <- das einfügen
String[] s = sb.ToString().Split('\0');

Der StringBuffer versucht warscheinlich die String-Länge zu bestimmen in dem es nach dem 0-Charakter sucht. Darum denke ich es würde evtl. funktionieren wenn du dem String-Buffer explizit die Länge angibst.

Mfg Stefan

Erstellt vor 15 Jahren

Hi iced-t89

Ja lustig nicht wahr? Es werden schon alle Sektionen zurückgegeben aber natürlich "Zero terminated". Das heisst du müsstest den Buffer durchhangeln und alle Strings sammeln bis du auf das "doppel null" stösst oder einfach die zurückgegebene länge erreichst. Meine C#-Kenntnisse sind zwar nicht existent und getestet habe ich es auch nicht aber vielleicht funktioniert es so:


private static List<String> SplitZeroTerminatedStrings(StringBuilder sb, Int32 len)
{
	List<String> strings = new List<String>();
	StringBuilder csb = new StringBuilder();
	
	for(Int32 i = 0; i < len; ++i)
	{		
		if(sb[i] != 0)
			csb.Append(sb[i]);
		else
		{
			if(csb.Length > 0)
			{
				strings.Add(csb.ToString());
				csb.Length = 0;
			}
		}
	}
	
	return(strings);
}

Mfg Stefan

Erstellt vor 15 Jahren

Hallo iced-t89

Probier es mal mit "null" statt "String.Empty".

Mfg Stefan

Erstellt vor 15 Jahren

Hallo Kaji

Das Problem liegt warscheinlich daran, dass die Aufrufkonventionen nicht zusammenpassen. Delphi verwendet imho Standardmässig "fastcall" und C# "stdcall".

Also am besten machst du die Delphi-Function zu einer stdcall Funktion in dem du "stdcall" zur Funktionsdeklaration hinzufügst:


function calculate (x,y : integer): integer; stdcall; export;
begin
  calculate := x+y;
end;

Mfg Stefan