Invalid Keystore Format Error๋ฅผ ๋Œ€ํ•˜๋Š” ์šฐ๋ฆฌ์˜ ์ž์„ธ

Java ๊ธฐ๋ฐ˜ ์‹œ์Šคํ…œ์„ ์šด์˜ํ•˜๋‹ค ๋ณด๋ฉด ๋ณด์•ˆ ์„ค์ •์„ ์œ„ํ•ด์„œ ์ธ์ฆ์„œ๋‚˜ ๋น„๋ฐ€ ํ‚ค๋ฅผ ์ €์žฅํ•˜๋Š” ํ‚ค์Šคํ† ์–ด๋ฅผ ์ž์ฃผ ๋‹ค๋ฃจ๊ฒŒ ๋œ๋‹ค.
ํŠนํžˆ java.io.IOException: Invalid Keystore Format ์˜ˆ์™ธ๋Š” ์–ด์ฉŒ๋ฉด ๊ฐ€์žฅ ์ž์ฃผ ๋งˆ์ฃผ์น˜๋Š” ์˜ˆ์™ธ์ผ ๊ฒƒ์ด๋‹ค.
์ด๋ฒˆ ํฌ์ŠคํŒ…์—์„œ๋Š” Baeldung์˜ ์ตœ์‹  ๊ฐ€์ด๋“œ๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ์ด ์—๋Ÿฌ์˜ ์›์ธ์„ ํŒŒ์•…ํ•˜๊ณ  ํ•ด๊ฒฐํ•˜๋Š” ์‹ค๋ฌด ๋…ธํ•˜์šฐ์— ๋Œ€ํ•ด์„œ ์ •๋ฆฌํ•˜๊ณ ์ž ํ•œ๋‹ค.

์ด ์—๋Ÿฌ๋Š” keystore ํŒŒ์ผ ํ˜•์‹๊ณผ Java ์ฝ”๋“œ์—์„œ ๊ธฐ๋Œ€ํ•˜๋Š” ํ˜•์‹(JKS, PKCS12๋“ฑ)์ด ์ผ์น˜ํ•˜์ง€ ์•Š๊ฑฐ๋‚˜ ๋นŒ๋“œ ๊ณผ์ • ๋˜๋Š” ์ „์†ก ์ค‘์— ํŒŒ์ผ์ด ์†์ƒ๋œ ๊ฒฝ์šฐ ๋ฐœ์ƒํ•˜๋ฉฐ ์ •ํ™•ํ•œ ์ง„๋‹จ ๋„๊ตฌ์™€ ์„ค์ •์„ ํ†ตํ•ด ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค.


Invalid Keystore Format Error์— ๋Œ€ํ•œ 3๊ฐ€์ง€ ์ฃผ์š” ํฌ์ธํŠธ

๊ฐœ๋ฐœ์ž ์—ฌ๋Ÿฌ๋ถ„๋“ค์ด ์ฃผ๋ชฉํ•ด์•ผ ํ•  ํ•ต์‹ฌ์ ์ธ ์—๋Ÿฌ ์›์ธ ๋ฐ ์ง„๋‹จ ๋ฐฉ๋ฒ•์„ ์„ธ๊ฐ€์ง€๋กœ ์ •๋ฆฌํ•ด ๋ณด์•˜๋‹ค.

์ฝ”๋“œ์™€ ํŒŒ์ผ ํ˜•์‹์˜ ๋ถˆ์ผ์น˜ ์„ ์–ธ

๊ฐ€์žฅ ํ”ํ•œ ์›์ธ ์ค‘ ํ•˜๋‚˜๋‹ค. ํŒŒ์ผ ์ž์ฒด๋Š” ์œ ํšจํ•œ PKCS#12(.p12 ๋˜๋Š” ํ™•์žฅ์ž๊ฐ€ ํ˜ผ๋™๋œ .jks) ํ˜•์‹์ธ๋ฐ ์ฝ”๋“œ์—์„œ KeyStore.getInstance(“JKS”)๋กœ ๋กœ๋“œํ•˜๋ ค๊ณ  ํ•˜๋Š” ๊ฒฝ์šฐ๋‹ค.
์ด ๊ฒฝ์šฐ ํŒŒ์ผ์˜ ํ˜•์‹์— ๋งž์ถฐ KeyStore.getInstance()์˜ ํƒ€์ž…์„ ์ •ํ™•ํžˆ ์ง€์ •ํ•ด์•ผ ํ•œ๋‹ค. (PKCS12 ๋˜๋Š” JKS)
๋‹จ์ˆœํžˆ ํŒŒ์ผ ํ™•์žฅ์ž๋งŒ์œผ๋กœ ํ™•์ธํ•  ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ์‹ค์ œ KeyStore ํŒŒ์ผ ํ˜•์‹์˜ ํ˜•์‹์„ ํ™•์ธํ•ด์•ผ ํ•œ๋‹ค.

keytool ๋ช…๋ น ํ™•์ธ

์ž๋ฐ”๊ฐ€ ์„ค์น˜๋˜์–ด ์žˆ๋‹ค๋ฉด keytool ๋ช…๋ น์„ ํ†ตํ•ด ํ™•์ธํ•ด ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

keytool -list -v -keystore ํŒŒ์ผ๋ช…
Bash

ํŒŒ์ผ ์‹œ๊ทธ๋‹ˆ์ฒ˜๋กœ ํ™•์ธ

ํŒŒ์ผ์˜ ์ฒซ 4byte ์ •๋ณด(ํŒŒ์ผ ์‹œ๊ทธ๋‹ˆ์ฒ˜)๋ฅผ ํ†ตํ•ด์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.
๋ฆฌ๋ˆ…์Šค๋‚˜ ๋งฅ ํ„ฐ๋ฏธ๋„์—์„œ xxd ๋ช…๋ น์„ ํ†ตํ•ด์„œ ํŒŒ์ผ์˜ ํ—ค๋”๋ฅผ ํ™•์ธํ•ด ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

# ํŒŒ์ผ์˜ ์ฒซ 1์ค„(16๋ฐ”์ดํŠธ)๋งŒ 16์ง„์ˆ˜๋กœ ์ถœ๋ ฅ
xxd -l 16 keystore.p12
Bash

์ถœ๋ ฅ

# JKS ํŒŒ์ผ
00000000: feed feed 0000 0002 ... 

# PKCS12 ํŒŒ์ผ
00000000: 3082 09c0 0201 0330 ...
Plaintext

๋ฐ”์ด๋„ˆ๋ฆฌ ํŒŒ์ผ์— ๋Œ€ํ•œ ๋นŒ๋“œ ๋„๊ตฌ์˜ ํ…์ŠคํŠธ ํ•„ํ„ฐ๋ง ํ™œ์„ฑํ™”

์˜์™ธ๋กœ ๋งŽ์€ ๊ฐœ๋ฐœ์ž๋“ค์ด ๋†“์น˜๋Š” ๋ถ€๋ถ„์ด๋‹ค. Maven์ด๋‚˜ Gradle ๊ฐ™์€ ๋นŒ๋“œ ๋„๊ตฌ๊ฐ€ ๋ฆฌ์†Œ์Šค๋ฅผ ์ฒ˜๋ฆฌํ•  ๋•Œ ๊ธฐ๋ณธ์ ์œผ๋กœ ํ…์ŠคํŠธ ํŒŒ์ผ์— ๋ณ€์ˆ˜ ์น˜ํ™˜(Filtering)์„ ์ ์šฉํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์€๋ฐ ์ด ๋•Œ ๋ฐ”์ด๋„ˆ๋ฆฌ ํŒŒ์ผ์ธ keystore ํŒŒ์ผ์ด ํ…์ŠคํŠธ ํ•„ํ„ฐ๋ง์ด ๋˜์–ด ๋‚ด์šฉ์ด ๋ณ€์กฐ๋˜๋Š” ๊ฒฝ์šฐ๋‹ค.
pom.xml ํ˜น์€ build.gradle ์„ค์ •์—์„œ keystore ํŒŒ์ผ์ด ํฌํ•จ๋œ ๋””๋ ‰ํ† ๋ฆฌ ํ˜น์€ ํ•ด๋‹น keystore ํŒŒ์ผ์— ๋Œ€ํ•ด์„œ๋Š” ๋ช…์‹œ์ ์œผ๋กœ ๋ฆฌ์†Œ์Šค ํ•„ํ„ฐ๋ง์„ ๋น„ํ™œ์„ฑํ™” ํ•ด์•ผ ํ•œ๋‹ค.

maven

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-resources-plugin</artifactId>
    <configuration>
        <nonFilteredFileExtensions>
            <nonFilteredFileExtension>p12</nonFilteredFileExtension>
            <nonFilteredFileExtension>pfx</nonFilteredFileExtension>
            <nonFilteredFileExtension>jks</nonFilteredFileExtension>
        </nonFilteredFileExtensions>
    </configuration>
</plugin>
XML

gradle

processResources {
    // ํ…์ŠคํŠธ ํŒŒ์ผ์€ ์น˜ํ™˜ํ•˜๋˜, ์ธ์ฆ์„œ ํŒŒ์ผ(.p12, .pfx)์€ ๊ฑด๋“œ๋ฆฌ์ง€ ์•Š๋„๋ก ์„ค์ •
    filesNotMatching(['**/*.p12', '**/*.pfx', '**/*.jks']) {
        expand(project.properties)
    }
}
Groovy

keytool ๋ฐ OpenSSL์„ ์ด์šฉํ•œ ์‚ฌ์ „ ์ง„๋‹จ

์ฝ”๋“œ ์ž‘์—… ์ด์ „์— ์šฐ์„  keystore ํŒŒ์ผ ์ž์ฒด์˜ ์œ ํšจ์„ฑ๊ณผ ๋‚ด์šฉ์„ ํ™•์ธํ•˜์—ฌ ์ด์ƒ์ด ์—†์Œ์„ ์šฐ์„  ์ฒดํฌํ•œ๋‹ค. ์•ž์„œ ์†Œ๊ฐœํ•œ keytool ๋ช…๋ น์„ ํ†ตํ•ด ํŒŒ์ผ ์œ ํ˜•๊ณผ ํ•จ๊ป˜ ์œ ํšจ์„ฑ์„ ์ฒดํฌํ•  ์ˆ˜ ์žˆ๋‹ค.

keytool -list -v -keystore ํŒŒ์ผ๋ช…
Bash

ํŒŒ์ผ์ด ์œ ํšจํ•˜๋ฉด ๋น„๋ฐ€๋ฒˆํ˜ธ ์ž…๋ ฅ ์š”์ฒญ์ด ์ƒ๊ธฐ๊ณ  keystore์— ๋Œ€ํ•œ ์ƒ์„ธ ์ •๋ณด๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค. ํŒŒ์ผ์ด ์ž˜๋ชป๋œ ํ˜•์‹์ธ ๊ฒฝ์šฐ์—๋Š” Exception ๋ฉ”์‹œ์ง€๊ฐ€ ์ถœ๋ ฅ๋œ๋‹ค.

openssl pkcs12 -info -in xxxx.jks
Bash

ํŒŒ์ผ ํ™•์žฅ์ž๊ฐ€ jks๋ผ๋„ ์‹ค์ œ๋กœ๋Š” PKCS#12 ํ˜•์‹์ผ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ OpenSSL ๋ช…๋ น์„ ์‚ฌ์šฉํ•ด ์‹ค์ œ ํ˜•์‹์„ ์ง„๋‹จํ•  ์ˆ˜ ์žˆ๋‹ค. ์œ„ ๋ช…๋ น์—์„œ ํŒŒ์ผ์„ ์„ฑ๊ณต์ ์œผ๋กœ ์ฝ๋Š” ๋‹ค๋ฉด xxxx.jks ํŒŒ์ผ์€ ์‹ค์ œ๋กœ PKCS#12 ํ˜•์‹์ž„์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.


์ฝ”๋“œ ์ž‘์—…

์œ„ ๋‚ด์šฉ์„ ํ†ตํ•ด keystore ํŒŒ์ผ ์œ ํ˜•๊ณผ ์œ ํšจ์„ฑ์„ ํŒŒ์•…ํ–ˆ๋‹ค๋ฉด ์ฝ”๋“œ ์ž‘์—…์— ์ฐฉ์ˆ˜ํ•œ๋‹ค.
ํŒŒ์ผ์ด PKCS#12 ํ˜•์‹์ด๋ผ๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋กœ๋”ฉํ•œ๋‹ค.

KeyStore ks = KeyStore.getInstance("PKCS12");
ks.load(new FileInputStream("keystore.p12"), "password".toCharArray());
Java

๊ธฐ์กด์˜ JKS ํ˜•์‹์ด๋ผ๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋กœ๋”ฉํ•œ๋‹ค.

KeyStore ks = KeyStore.getInstance("JKS");
ks.load(new FileInputStream("keystore.jks"), "password".toCharArray());
Java

์•ž์„œ ์•Œ์•„๋ณธ ๋ฐ”์™€ ๊ฐ™์ด ์ฝ”๋“œ ๋‚ด keystore ํ˜•์‹์ด ์‹ค์ œ ํŒŒ์ผ ํ˜•์‹๊ณผ ์ผ์น˜ํ•˜๋„๋ก ํ•˜๋ฉด java๊ฐ€ ๋ฐ์ดํ„ฐ๋ฅผ ์ž˜๋ชป ํ•ด์„ํ•˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•˜๊ณ  ํ˜•์‹ ์˜ค๋ฅ˜๋ฅผ ์ œ๊ฑฐํ•  ์ˆ˜ ์žˆ๋‹ค.

ํ˜•์‹ ๋ณ€๊ฒฝ

๊ทธ๋ž˜๋„ keystore ํ˜•์‹์ด ์˜ˆ์ƒ๋œ ๊ฒƒ๊ณผ ์ผ์น˜ํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด keytool์„ ํ†ตํ•ด ๋ณ€ํ™˜ํ•  ์ˆ˜ ์žˆ๋‹ค.

$ keytool -importkeystore \
  -srckeystore keystore.p12 -srcstoretype pkcs12 \
  -destkeystore keystore.jks -deststoretype jks
Bash

๋ณ€ํ™˜ ํ›„ keytool -list ๋ช…๋ น์„ ํ†ตํ•ด์„œ ๋ณ€ํ™˜๋œ ํŒŒ์ผ์ด ์ด์ƒ์—†์ด ๋กœ๋“œ๋˜๋Š”์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.


keystore ํ˜•์‹ ์—๋Ÿฌ๋Š” ์ž์ฃผ ๋ฐœ์ƒํ•˜์ง€๋งŒ ํ•ด๊ฒฐ์ฑ…์€ ์˜์™ธ๋กœ ๊ฐ„๋‹จํ•˜๋‹ค. keystore ํŒŒ์ผ์˜ ์‹ค์ œ ํ˜•์‹๊ณผ ์ฝ”๋“œ์˜ ๊ธฐ๋Œ€ ํ˜•์‹์„ ์ผ์น˜์‹œํ‚ค๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•˜๊ณ  ํŒŒ์ผ์ด ๋ณ€์กฐ๋˜์ง€ ์•Š๋„๋ก ๊ด€๋ฆฌํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

์ฐธ๊ณ ๋งํฌ (๋ฐธ๋ฉ)

https://www.baeldung.com/java-resolve-ioexception-invalid-keystore-format-error