공개키 구조
n값과 e값으로 구성되어있다.
n값은 Modulus이며 e값은 Public exponent값입니다.
Modulus
모듈러스는 공개키에서 중요한 역할을 하며, 두 큰 소수인 p와 q의 값으로 계산된다.
이 값은 RSA 알고리즘의 핵심인 모듈러 연산에서 사용된다.
구체적으로 모듈러스는 공개키와 개인키의 연산에 사용되며, RSA 암호화 및 복호화에서 중요한 역할을 한다.
p와 q는 매우 큰 소수들이다.
이 값은 공개키와 객인키 모두에서 사용되며, 키의 길이는 이 값의 크기에 따라 결정된다.
RSA 키의 보안은 이 묘듈러 연산의 특성에 의존하며, 큰 소수의 곱을 소인수 분해하는 것은 매우 어려운 문제이다.
Exponent(공개키 지수)
공개키 지수는 보통 e로 표시되며, 이 값은 공개키의 일부로 다른 사람에게 알려진다.
공개 키 지수는 암호화 연사에서 메세지를 암호화 하는데 사용된다.
위의 xml 데이터(링크에서 확인하라는데 링크 속 주소가 없어짐, 이건 뭘까?)는 모두 문자열을 담고 있다.
바이너리(2진수)인 이 데이터를 담기 위해서는 인코딩이 필요합니다.
여기서 사용되는 인코딩이 Base64 인코딩입니다.
Rsa256 알고리즘으로 id token 서명을 검증하는 방법
RSA256은 RSA 알고리즘을 사용하여 SHA-256 해시 함수를 적용한 서명 알고리즘이다.
서명 검증 과정
1. JWT 구조 파싱
header.payload.signature
header : JWT 헤더에는 사용된 알고리즘이 명시된다.
payload : 실제 데이터(주로 클레임)가 포함된다.
signature : 헤더와 페이로드가 서명된 값이다.
2.헤더에서 알고리즘 추출
JWT의 헤더 부분에서 사용된 서명 알고리즘을 확인한다.
이 알고리즘이 RSA256인지 확인해야함.
3.서명 검증
- 먼저 헤더와 페이로드는 base64로 인코딩된 문자열이다. 이를 디코딩하여 원본데이터를 얻는다.
- 디코딩한 헤더와 페이로드를 Base64 URL-safe 형식으로 다시 인코딩해서 결합한다. 이때 헤더와 페이로드는 .으로 구분되어있다.
- "\(encodedHeader).\(encodedPayload)"
- 서명 부분을 base64 디코딩하여, 실제 서명을 얻는다.
- RSA 공개키로 서명 검증은 진행한다. 공개키로 서명된 데이터의 해시 값과 디코딩된 서명 값이 일치하는 지 확인한다.
- 공개 키로 데이터를 서명하는 방법과 그 데이터의 해시값을 얻는 방법
import Foundation
import Security
func verifyRSASignature(jwt: String, publicKey: SecKey) -> Bool {
let segments = jwt.split(separator: ".")
guard segments.count == 3 else {
return false
}
let headerPayload = "\(segments[0]).\(segments[1])"
// Base64url decode signature
guard let signatureData = base64urlDecode(String(segments[2])) else {
return false
}
// Create SHA256 hash of the message
guard let messageData = headerPayload.data(using: .utf8) else {
return false
}
let hash = sha256(messageData)
// Verify signature with RSA public key
return verifySignature(signatureData, withHash: hash, publicKey: publicKey)
}
func base64urlDecode(_ string: String) -> Data? {
let modifiedString = string.replacingOccurrences(of: "-", with: "+").replacingOccurrences(of: "_", with: "/")
let paddingLength = (4 - modifiedString.count % 4) % 4
let paddedString = modifiedString + String(repeating: "=", count: paddingLength)
return Data(base64Encoded: paddedString)
}
func sha256(_ data: Data) -> Data {
var hash = Data(count: Int(CC_SHA256_DIGEST_LENGTH))
_ = hash.withUnsafeMutableBytes { hashBytes in
data.withUnsafeBytes { messageBytes in
CC_SHA256(messageBytes.baseAddress, CC_LONG(data.count), hashBytes.baseAddress)
}
}
return hash
}
func verifySignature(_ signature: Data, withHash hash: Data, publicKey: SecKey) -> Bool {
var error: Unmanaged<CFError>?
let isValid = SecKeyVerifySignature(publicKey,
.rsaSignatureMessagePKCS1v15SHA256,
hash as CFData,
signature as CFData,
&error)
return isValid
}
참조 블로그
https://byul91oh.tistory.com/272
[RSA] RSA MODULUS, EXPONENT
RSA키는 비대칭키로 개인키와 공개키로 되어있습니다. 여기서 공개키와 개인키는 위에서 보시는 것과 같이 구조가 되어 있습니다. 일반적으로 공개키는 n값과 e 값으로 구성되어 있습니다. n값은
byul91oh.tistory.com
https://stackoverflow.com/questions/65361511/swift-load-rsa-public-key-from-string-macos
'ios' 카테고리의 다른 글
[iOS] 하나의 뷰컨트롤러에 iPad와 iPhone 두개의 xib 연결하기 (0) | 2025.02.26 |
---|---|
[iOS] present VS addChild, dismiss (0) | 2025.02.25 |
ios에서 적은 메모리로 이미지를 만들기(공부) (2) | 2024.12.13 |
storekit 공부하기 (0) | 2024.12.06 |
15. URLRequest (0) | 2024.04.16 |