APNs 서버에 통신하기 위해 인증하는 방법은 p8 인증서를 통한 토큰 인증 방식과 p12 인증서를 통한 인증서 인증 방식이 있다. p12 인증서 방식을 사용하면 1년에 한번씩 인증서를 새로 갱신해야 하기 때문에 여간 불편한게 아니기 때문에 아마 대부분은 p8 인증서를 통한 토큰 인증 방식을 사용하고 있을 것이다. 하지만 개발환경이라는게 이래저래 다양하고, 어떤 곳에서는 p12 인증서를 써야할 수 있다. 1년에 한번 하는게 그렇게 어려운 것도 아니고…

하지만 1년에 한번이라는게 문제다. 1년만에 해보려니까 이래저래 헷갈릴 수가 있단 말이지. 다행히 애플측에서 인증서 발급과 관련해서 한국어 문서를 제공하고 있기 때문에(인증서 서명 요청 생성하기, TLS 인증서를 사용하여 APNs와 커뮤니케이션하기) 그렇게 어렵지는 않다. 다만 우리측 서버에 등록할 인증서와 키를 p12가 아닌 pem 파일로 변환해서 써야할 때가 있는데, 당연하게도 애플에서 딱히 이를 위한 방법을 알려주진 않는다. 그래서 열심히 검색을 해보면 아래와 같은 방법을 써보라고 나오는데…

# 1. 인증서 파일 변환하기
# apns-cert.p12 파일을 apns-cert.pem으로 변환한다고 했을때
$ openssl pkcs12 \
    -clcerts \
    -nokeys \
    -out apns-cert.pem \
    -in apns-cert.key
    
# 2. 키 파일 변환하기
# apns-key.p12 파일은 apns-key.pem으로 변환한다고 했을때
$ openssl pkcs12 \
    -nocerts \
    -out apns-key.pem \
    -in apns-key.p12

이걸 보고 그대로 따라하면 아마 높은 확률로 아래와 같은 오류 메시지를 마주하게 될 것이다.

… :digital envelope routines:inner_evp_generic_fetch:unsupported:crypto/evp/evp_fetch.c:349:Global default library context, Algorithm (RC2-40-CBC : 0), Properties ()

대충 읽어보면 unsupported, Algorithm, RC2-40-CBC와 같은 키워드가 눈에 보인다. 그러니까 정리하자면 RC2-40-CBC 알고리즘을 지원하지 않는다는 얘기인 것 같다. 아마도 애플에서 제공하는 p12 파일의 암호화에 RC2-40-CBC 알고리즘이 쓰이는 모양이다. 그렇다면 방법이 없을까? 그렇지 않다. openssl pkcs12 의 옵션을 차근차근 살펴보면 해당 알고리즘은 사용하도록 하는 옵션인 -legacy 가 있다. 해당 옵션에 대해서는 아래와 같이 설명하고 있다.

In the legacy mode, the default algorithm for certificate encryption is RC2_CBC or 3DES_CBC depending on whether the RC2 cipher is enabled in the build. The default algorithm for private key encryption is 3DES_CBC. If the legacy option is not specified, then the legacy provider is not loaded and the default encryption algorithm for both certificates and private keys is AES_256_CBC with PBKDF2 for key derivation.

축약해서 말하자면 레거시 모드에서는 인증서 암호화를 위한 기본 알고리즘은 RC2_CBC나 3DES_CBC을 쓴단 말이다. 그러니 위의 명령어 입력에 적당히 -legacy 옵션을 껴넣어주면 문제없이 동작하는 것을 알 수 있다.