티스토리 뷰
Dev./Kotlin
[Kotlin] java.security.InvalidKeyException: IOException : algid parse error 원인
인쥭 2023. 3. 21. 10:58반응형
CloudFront Signed URL을 만드는 과정에서, 문자열로 된 RSA Key를 아래와 같은 코드를 통해 java.security.PrivateKey 인스턴스로 변환하고자 했다.
internal fun String.convertToPrivateKey(): PrivateKey {
val keyData = this.replace("-----BEGIN RSA PRIVATE KEY-----\n", "")
.replace("-----END RSA PRIVATE KEY-----", "")
.replace("\n", "")
val keyBytes = Base64.getDecoder().decode(keyData)
val keySpec = PKCS8EncodedKeySpec(keyBytes)
return KeyFactory.getInstance("RSA")
.generatePrivate(keySpec)
}
그러나 돌아오는 것은 차가운 에러 뿐
2023-03-21 10:00:00.000 ERROR 3505 --- [io-60805-exec-2] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: IOException : algid parse error, not a sequence] with root cause
java.security.InvalidKeyException: IOException : algid parse error, not a sequence
// ...생략
원인은 내가 사용한 키에 적용된 암호화 표준은 pkcs#1이나, 정작 PKCS8EncodedKeySpec를 통해 PrivateKey로 변환을 시도했기 때문에 발생한 오류였다.
따라서 다음과 같은 흐름으로 문제를 해결해야 한다.
- pkcs#1 키를 pkcs#8로 수정한다.
- 상술한 String 확장 함수를 살짝 변경해준다.
참고로, 내 키가 pkcs#1인지 pkcs#8인지 확인하는 방법은 키의 헤더와 푸터를 보면 된다.
예를 들어, pkcs#1은 헤더가 -----BEGIN RSA PRIVATE KEY-----인 반면 pkcs#8은 -----BEGIN PRIVATE KEY-----이다.
우선, pkcs#1 키를 pkcs#8로 수정하는 openssl 명령어는 다음과 같다.
[~] openssl pkcs8 -topk8 -in ~/Downloads/my.key -out my.pkcs8.key -nocrypt
[~] ls
my.pkcs8.key
[~]
BouncyCastle이라는 라이브러리로 코드 상에서 수정도 가능하다고 했는데, 되도록이면 라이브러리를 사용하고 싶지 않아 키 자체를 수정하는 방법을 택했다.
다음으로, pkcs#8 키는 헤더가 다르기에 상술한 String.convertToPrivateKey() 확장 함수를 아래와 같이 수정한다.
internal fun String.convertToPrivateKey(): PrivateKey {
val keyData = this.replace("-----BEGIN PRIVATE KEY-----\n", "")
.replace("-----END PRIVATE KEY-----", "")
.replace("\n", "")
val keyBytes = Base64.getDecoder().decode(keyData)
val keySpec = PKCS8EncodedKeySpec(keyBytes)
return KeyFactory.getInstance("RSA")
.generatePrivate(keySpec)
}
끗
'Dev. > Kotlin' 카테고리의 다른 글
[Kotlin] 인자에 따라 List를 규칙적으로 뒤섞기 (0) | 2025.03.17 |
---|---|
[mockk] private extension function 모킹하기 (0) | 2024.10.28 |
[Kotlin] Class should have [public, protected] no-arg constructor 해결법 (0) | 2024.02.25 |
[Kotlin] Scope Functions (0) | 2023.10.23 |
[SpringBoot] WebTestClient NoSuchBeanDefinitionException 예외 해결법 (0) | 2023.04.19 |
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- Puppeteer
- 코딩테스트
- etc
- RancherDesktop
- Linux
- mysql
- Git
- jQuery
- JEST
- JPA
- react
- terraform
- Vault
- IntelliJ
- AWS IoT
- spring boot
- Gradle
- Spring Cloud Config
- Java
- javascript
- pgloader
- postgresql
- kotlin
- Node.js
- hashicorp
- Database
- Docker
- AWS
- eureka
- shell
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
글 보관함