admin管理员组文章数量:1180476
i write this code and a lot of error , i fixed a lot error and this last error and i dont understand whats that mean and how to fix
package com.example.nfcpassportttbapi.NfcController;
import java.awt.image.BufferedImage;
import java.io.InputStream;
import java.security.spec.AlgorithmParameterSpec;
import java.util.*;
import javax.smartcardio.*;
import org.jmrtd.AccessKeySpec;
import org.jmrtd.BACKey;
import org.jmrtd.BACKeySpec;
import org.jmrtd.PassportService;
import org.jmrtd.lds.icao.DG1File;
import org.jmrtd.lds.icao.DG2File;
import org.jmrtd.lds.icao.MRZInfo;
import org.jmrtd.lds.iso19794.FaceImageInfo;
import org.jmrtd.lds.iso19794.FaceInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class PassportController {
private static final Logger log =
LoggerFactory.getLogger(PassportController.class);
private List<String> extractOIDsFromCardAccess(byte[] cardAccessData) {
List<String> oids = new ArrayList<>();
int index = 0;
while (index < cardAccessData.length) {
int tag = cardAccessData[index++] & 0xFF;
// ตรวจสอบว่าเป็น OID (Tag 0x06)
if (tag == 0x06) {
int length = cardAccessData[index++] & 0xFF;
byte[] oidBytes =
Arrays.copyOfRange(cardAccessData, index, index + length);
index += length;
// แปลง OID เป็นสตริง
StringBuilder oid = new StringBuilder();
for (int i = 0; i < oidBytes.length; i++) {
int value = oidBytes[i] & 0xFF;
if (i == 0) {
oid.append(value / 40).append(".").append(value % 40);
} else {
oid.append(".").append(value);
}
}
oids.add(oid.toString());
} else {
// ข้าม tag อื่น ๆ
int length = cardAccessData[index++] & 0xFF;
index += length;
}
}
return oids;
}
@GetMapping("/api/passport/read")
public ResponseEntity<?> readPassport() {
var result = new HashMap<String, Object>();
try {
// (1) ตั้งค่าข้อมูล BAC Key
String passportNumber = "";
String dateOfBirth = ""; // YYMMDD
String dateOfExpiry = ""; // YYMMDD
BACKeySpec bacKey = new BACKey(passportNumber, dateOfBirth, dateOfExpiry);
log.info("BACKey => number={}, dob={}, doe={}", passportNumber,
dateOfBirth, dateOfExpiry);
// (2) ตรวจสอบเครื่องอ่านบัตร
TerminalFactory factory = TerminalFactory.getDefault();
List<CardTerminal> terminals = factory.terminals().list();
if (terminals.isEmpty()) {
log.warn("No PC/SC readers found.");
result.put("error", "No PC/SC readers found");
return ResponseEntity.badRequest().body(result);
}
CardTerminal terminal = terminals.get(0);
log.info("Using terminal: {}", terminal.getName());
// (3) รอจนกว่าจะมีบัตร
if (!terminal.isCardPresent()) {
log.info("Please place ePassport on the reader... (no timeout)");
terminal.waitForCardPresent(0);
}
// (4) เชื่อมต่อกับบัตร
Card card = terminal.connect("*");
Test2 cs = new Test2(card); // ใช้ Test2 เป็น Custom CardService
cs.open();
log.info("Connected to card and opened CardService.");
try {
CardChannel cardChannel = card.getBasicChannel();
// ส่งคำสั่ง SELECT FILE
byte[] apduCommand = new byte[] {0x00, (byte) 0xA4, 0x04, 0x0C, 0x00};
ResponseAPDU responseAPDU =
cardChannel.transmit(new CommandAPDU(apduCommand));
if (responseAPDU != null) {
int sw = responseAPDU.getSW(); // อ่านค่า Status Word (SW)
log.info("APDU Response SW: {}", Integer.toHexString(sw));
// ตรวจสอบว่าบัตรตอบกลับด้วยค่า 0x9000 (Success) หรือไม่
if (sw == 0x9000) {
log.info("APDU command succeeded!");
} else {
log.warn("APDU command failed, SW: {}", Integer.toHexString(sw));
}
} else {
log.error("ResponseAPDU is null, no response from the card");
}
} catch (Exception e) {
log.error(
"Exception while sending APDU command: {}", e.getMessage(), e);
result.put("error", "APDU command failed: " + e.getMessage());
cs.close();
card.disconnect(false);
return ResponseEntity.badRequest().body(result);
}
// (5) เปิด PassportService
PassportService service =
new PassportService(cs, PassportService.NORMAL_MAX_TRANCEIVE_LENGTH,
PassportService.DEFAULT_MAX_BLOCKSIZE, true, false);
service.open();
log.info("PassportService opened.");
try {
boolean paceSuccess = false;
// ดึงข้อมูล EF.CardAccess
byte[] cardAccessData =
service.getInputStream(PassportService.EF_CARD_ACCESS)
.readAllBytes();
List<String> oids = extractOIDsFromCardAccess(cardAccessData);
log.info("PACE OIDs: {}", oids);
for (String oid : oids) {
try {
service.doPACE(bacKey, oid, null);
log.info("PACE succeeded with OID: {}", oid);
paceSuccess = true;
break;
} catch (Exception e) {
log.warn("PACE failed with OID {}: {}", oid, e.getMessage());
}
}
if (!paceSuccess) {
log.warn("PACE failed, trying BAC...");
service.doBAC(bacKey);
log.info("BAC succeeded.");
}
} catch (Exception e) {
log.error("Authentication failed: {}", e.getMessage(), e);
result.put("error", "Authentication failed: " + e.getMessage());
cs.close();
card.disconnect(false);
return ResponseEntity.badRequest().body(result);
}
// (8) อ่าน DG1 -> MRZ
try (InputStream dg1Input =
service.getInputStream(PassportService.EF_DG1)) {
DG1File dg1File = new DG1File(dg1Input);
MRZInfo mrzInfo = dg1File.getMRZInfo();
log.info("Document Number: {}", mrzInfo.getDocumentNumber());
log.info(
"Name: {}", mrzInfo.getSecondaryIdentifier().replace("<", " "));
log.info(
"Surname: {}", mrzInfo.getPrimaryIdentifier().replace("<", " "));
result.put("documentNumber", mrzInfo.getDocumentNumber());
result.put(
"name", mrzInfo.getSecondaryIdentifier().replace("<", " ").trim());
result.put(
"surname", mrzInfo.getPrimaryIdentifier().replace("<", " ").trim());
result.put("dateOfBirthMRZ", mrzInfo.getDateOfBirth());
result.put("dateOfExpiryMRZ", mrzInfo.getDateOfExpiry());
result.put("nationality", mrzInfo.getNationality());
}
// (9) อ่าน DG2 -> รูปใบหน้า
try (InputStream dg2Input =
service.getInputStream(PassportService.EF_DG2)) {
DG2File dg2File = new DG2File(dg2Input);
List<FaceInfo> faceInfos = dg2File.getFaceInfos();
List<FaceImageInfo> faceImages = new ArrayList<>();
for (FaceInfo faceInfo : faceInfos) {
faceImages.addAll(faceInfo.getFaceImageInfos());
}
if (!faceImages.isEmpty()) {
FaceImageInfo faceImageInfo = faceImages.get(0);
BufferedImage image = ImageUtil.toBufferedImage(faceImageInfo);
String faceBase64 = ImageUtil.toBase64(image);
result.put("faceImageBase64", faceBase64);
log.info("Face image read and converted to base64.");
} else {
log.warn("No face images in DG2");
result.put("warningDG2", "No face images in DG2");
}
}
// (10) ปิดการเชื่อมต่อ
cs.close();
card.disconnect(false);
log.info("Disconnected card/CS. Done reading ePassport.");
result.put("status", "success");
return ResponseEntity.ok(result);
} catch (Exception e) {
log.error("Exception in readPassport: {}", e.getMessage(), e);
var errorResult = new HashMap<String, Object>();
errorResult.put("error", e.getMessage());
return ResponseEntity.internalServerError().body(errorResult);
}
}
}
the requirement is i have a reader ACR1281 and i have epassport i must scan with nfc and show result of passport, the passport is good , and reader is not broke
本文标签:
版权声明:本文标题:java - [SprintBoot][Epassport]Authentication failed: Cannot invoke "net.sf.scuba.smartcards.ResponseAPDU.getSW()&qu 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1738133363a2065337.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论