728x90
반응형

다음으로 쿠키 세팅과 파라미터 세팅을 해야함

 

1. 인증서 로그인에 필요한 쿠키를 세팅

헤더 세팅 값
Content-Type application/x-www-form-urlencoded; charset=UTF-8
Cookie WMONID, TXPPsessionID

 

https://www.hometax.go.kr/wqAction.do?actionId=ATXPPZXA001R01&screenId=UTXPPABA01

위의 API GET 요청을 통해 쿠키 정보를 가져와  WMONID, TXPPsessionID 정보를 세팅하고, 파마미터 세팅에 중요한 값인 Response에서 pkcEncSsn에 담긴 값을 가져옴

 

아래와 같이 Header 세팅을 해줌

HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
headers.set(HttpHeaders.COOKIE, cookies);

 

2. 파라미터 세팅

파라미터 명 세팅 값
logSgnt pkcEncSsn $ 공개키 인증서 일련번호 $ yyyyMMddHHmmss $ 전자 서명 값
cert 공개키 PEM 값
randomEnc 개인키에서 찾은 randomNum 값
pkcLoginYnImpv Y (하드 코딩)
pkcLgnClCd 04 (하드코딩)

 

위의 파라미터에서 설명이 필요한 부분은 logSgnt와 randomEnc 임

 

logSgnt 세팅에 필요한 값은 총 4개인데, 그 4개의 값을 $로 합치고 Base64로 인코딩 한 후 logSgnt로 담아 보냄

(1) pkcEncSsn은 1번의 요청의 Response pkcEncSsn의 값

(2) 공개키 인증서 일련번호 공개키의 SerialNumber 값

(3) yyyyMMddHHmmss 값

String currentDate = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));

 

(4) pkcEncSsn으로 전자 서명한 값

      알고리즘 SHA256withRSA 방식으로 개인키를 전자 서명한 값이 필요함

 

randomEnc는 개인키에서 randomNum을 찾아 세팅해 줘야 함

이를 위해선 개인키의 포맷을 확인하고 (한국 전자 인증의 경우 pkcs5PBES2) 그에 맞는 복호화를 통해서 randomNum 값을 찾음

// 복호화
public String decryptKey(String password) {
    try {
        byte[] decryptedKey = null;
        byte[] encodedKey = FileUtils.readBinary(filePath);

        EncryptedPrivateKeyInfo encryptedPrivateKeyInfo = null;
        try (ByteArrayInputStream bIn = new ByteArrayInputStream(encodedKey);
            ASN1InputStream aIn = new ASN1InputStream(bIn);) {
			
            ASN1Sequence asn1Sequence = (ASN1Sequence) aIn.readObject();
			
            AlgorithmIdentifier algId = AlgorithmIdentifier.getInstance(asn1Sequence.getObjectAt(0));
            ASN1OctetString data = ASN1OctetString.getInstance(asn1Sequence.getObjectAt(1));
			
            encryptedPrivateKeyInfo = new EncryptedPrivateKeyInfo(algId, data.getEncoded());
			
            String privateKeyAlgName = encryptedPrivateKeyInfo.getEncryptionAlgorithm().getAlgorithm().getId();

            if ("1.2.840.113549.1.5.13".equals(privateKeyAlgName)) { // pkcs5PBES2
                // 개인키 암호화 정보에서 Salt, Iteration Count(IC), Initial Vector(IV)를 가져오는 로직
                ASN1Sequence asn1Sequence2 = (ASN1Sequence) algId.getParameters();
                ASN1Sequence asn1Sequence3 = (ASN1Sequence) asn1Sequence2.getObjectAt(0);
				
                // PBKDF2 Key derivation algorithm
                ASN1Sequence asn1Sequence33 = (ASN1Sequence) asn1Sequence3.getObjectAt(1);

                // Salt 값
                DEROctetString derOctetStringSalt = (DEROctetString) asn1Sequence33.getObjectAt(0);

                // Iteration Count(IC)
                ASN1Integer asn1IntegerIC = (ASN1Integer) asn1Sequence33.getObjectAt(1);
                ASN1Sequence asn1Sequence4 = (ASN1Sequence) asn1Sequence2.getObjectAt(1);

                // Initial Vector(IV)
                DEROctetString derOctetStringIV = (DEROctetString) asn1Sequence4.getObjectAt(1);

                // 복호화 키 생성
                int keySize = 256;
                PBEParametersGenerator generator = new PKCS5S2ParametersGenerator();
                generator.init(
                    PBEParametersGenerator.PKCS5PasswordToBytes(password.toCharArray()),
                    derOctetStringSalt.getOctets(),
                    asn1IntegerIC.getValue().intValue());

                byte[] iv = derOctetStringIV.getOctets();

                KeyParameter key = (KeyParameter) generator.generateDerivedParameters(keySize);

                // 복호화 수행
                IvParameterSpec ivSpec = new IvParameterSpec(iv);
                SecretKeySpec secKey = new SecretKeySpec(key.getKey(), "SEED");

                Cipher cipher = Cipher.getInstance("SEED/CBC/PKCS5Padding", "BC");
                cipher.init(Cipher.DECRYPT_MODE, secKey, ivSpec);
                decryptedKey = cipher.doFinal(data.getOctets());
            }
        } catch (Exception e) {
            ...
        }
    ...
}

 

복호화 후 id-randomNum를 찾기

아래 사이트에서 확인해보면 OID(오브젝트 고유 번호)

http://www.oid-info.com/cgi-bin/display?oid=1.2.410.200004.10.1.1.3&submit=Display&action=display

randomNum의 OID가 1.2.410.200004.10.1.1.3 인 걸 확인할 수 있음

이 값을 찾아서 세팅해주기

반응형
복사했습니다!