Hallo zusammen,
weiß irgendjemand wie ich aus einer Krankenversicherungskarte, bei der das Terminal nach ASN.1-Format eingestellt ist, die Daten auslesen kann?
zwar gibt es viele Doku´s, die aber nicht sagen (zumindest verstehe ich es nicht) wie man die Daten strukturiert auslesen kann.
Ich habe folgendes erfolgreich gemacht:
ct_init,
reset_ct (Command = 0x20, 0x11, 0x00, 0x00, 0x00),
request_icc (Command = 0x20, 0x12, 0x01, 0x00),
get_status (Command = 0x20, 0x13, 0x00, 0x46, 0x00);
--> gem Byte 45 ist Terminal in ASN.1-Format
select_file (Command = 0x00, 0xA4, 0x04, 0x00, 0x06, 0xD2, 0x76, 0x00, 0x00, 0x01, 0x01);
read_binary (Command = 0x00, 0xB0, 0x00, 0x00, 0x00);
--> dabei erhalte ich aber nur die gesamten Daten in variabler Länge, was eigentlich nicht so schlimm wäre, wenn nicht Felder wie Titel, Namenszusatz, WOC fehlen würden, da nicht gefüllt.
Also muß ich wohl die Daten über das Application-File auslesen.
Ich habe aber leider keinen blassen Schimmer wie ich die TAG´s einzeln auslesen soll?
zb.: Tag 80 = Krankenkassenname
Tag 81 = KrankenkassenNr
...
Tag 8E = Prüfsumme
Kann mir da bitte mal jemand auf die Sprünge helfen?
MfG ChrisProg
Hier mal meine Methode um die KVK-Daten auszulesen:
public bool GetKVKData(CardData cardData, bool deleteData)
{
if (cardData == null)
throw new ArgumentNullException("cardData", "CardData darf nicht null sein.");
this.CardType = CardTypes.KVK;
if (this.CT_init() &&
(this.CT_data(eCtCommands.ResetCT) &&
(this.CT_data(eCtCommands.RequestICC) || (this.CT_data(eCtCommands.RequestICC2))) &&
((this.CT_data(eCtCommands.SelectFile)) || this.CT_data(eCtCommands.SelectFile2)) &&
this.CT_data(eCtCommands.ReadBinary_Person))
)
{
for (int i = 0; i < this.lastResponse.Count; i++)
{
if ((i + 1) < this.lastResponse.Count)
{
int length = Convert.ToInt16(this.lastResponse[i + 1]);
switch (Convert.ToString(int.Parse(this.lastResponse[i].ToString(CultureInfo.CurrentCulture), CultureInfo.CurrentCulture), 16).ToUpper(CultureInfo.CurrentCulture))
{
case "80":
if (length > 0 && length <= 28)
cardData.KKName = this.getKVKFieldData(ref i, length);
break;
case "81":
if (length > 0 && length == 7)
cardData.KKNummer = this.getKVKFieldData(ref i, length);
break;
case "82":
if (length > 0 && length <= 12)
cardData.VersNummer = this.getKVKFieldData(ref i, length);
break;
case "83":
if (length > 0 && length <= 4)
cardData.VersStatus = this.getKVKFieldData(ref i, length);
break;
case "84":
if (length > 0 && length <= 15)
cardData.Titel = this.getKVKFieldData(ref i, length);
break;
case "85":
if (length > 0 && length <= 15)
cardData.Vorname = this.getKVKFieldData(ref i, length);
break;
case "86":
if (length > 0 && length <= 15)
cardData.NamensZusatz = this.getKVKFieldData(ref i, length);
break;
case "87":
if (length > 0 && length <= 28)
cardData.Familienname = this.getKVKFieldData(ref i, length);
break;
case "88":
if (length > 0 && length == 8)
cardData.GeburtsDatum = DateTime.ParseExact(this.getKVKFieldData(ref i, length), "ddMMyyyy", CultureInfo.InvariantCulture.DateTimeFormat);
break;
case "89":
if (length > 0 && length <= 28)
cardData.Strasse = this.getKVKFieldData(ref i, length);
break;
case "90":
if (length > 0 && length <= 3)
cardData.VersStatusErg = this.getKVKFieldData(ref i, length);
break;
case "8A":
if (length > 0 && length <= 3)
cardData.LaenderCode = this.getKVKFieldData(ref i, length);
break;
case "8B":
if (length > 0 && length <= 7)
cardData.PLZ = this.getKVKFieldData(ref i, length);
break;
case "8C":
if (length > 0 && length <= 22)
cardData.Ort = this.getKVKFieldData(ref i, length);
break;
case "8D":
if (length > 0 && length == 4)
{
string date = this.getKVKFieldData(ref i, length);
cardData.Gueltigkeit = DateTime.Parse("01." + date.Substring(0, 2) + "." + date.Substring(2, 2), CultureInfo.CurrentCulture).AddMonths(1).AddDays(-1);
}
break;
case "8F":
if (length > 0 && length <= 5)
cardData.VKNr = this.getKVKFieldData(ref i, length);
break;
case "91":
if (length > 0 && length == 8)
{
string dateRead = this.getKVKFieldData(ref i, length);
DateTime dateTime;
if (DateTime.TryParseExact(dateRead, "ddMMyyyy", CultureInfo.InvariantCulture.DateTimeFormat, DateTimeStyles.None, out dateTime))
cardData.EinleseDatum = dateTime.ToString("dd.MM.yyyy", CultureInfo.CurrentCulture);
else
cardData.EinleseDatum = dateRead;
}
break;
}
}
}
if (deleteData)
this.CT_data(eCtCommands.EraseBinary);
this.CT_close();
return true;
}
this.CT_close();
return false;
}
private string getKVKFieldData(ref int index, int length)
{
byte[] data = new byte[length];
this.lastResponse.CopyTo(index + 2, data, 0, length);
index += length;
return Encoding.GetEncoding(20106).GetString(data, 0, length); //Aus KVK Spezifikation: DIN 66003
}
Hallo Joetempes,
danke für Deine Antwort. Wie vermutet habe ich den Baum vor lauter Wald nicht gesehen:
ich hab mir das ResponseArray im Debugger angeschaut, und dabei nicht beachtet, das mir die Werte ja in dezimal angezeigt werden 😜
Danke 👍
Weist Du oder auch ein anderer geschätzter Kollege zufällig auch wie ich die Versichertendaten aus einer eGK korrekt auslesen kann:
denn lt: "gematik_Leitfaden_Implementierung_Lesen_eGK_V120.pdf"
muß ich
das gleiche passiert beim Versuch die VD oder die GVD auszulesen.
Im Anhang B des o.g. PDF´s steht sogar ein " CT-Api-Protokoll einer Leseroutine" wo ich genau sehen kann wie Sie die Commands aufgebaut haben, aber ich bekomme immer nur ungültiger Parameter zurück.
Wie gesagt, ich brauche nur die Versichertendaten (wie in der KVK auch), der geschützte Bereich interessiert mich im Moment überhaupt nicht.
Für weitere Hilfe wäre ich sehr dankbar.
MfG ChrisProg