Skip to content

Instantly share code, notes, and snippets.

@benbenbenbenbenben
Last active November 29, 2024 11:26
Show Gist options
  • Save benbenbenbenbenben/79d9e0862f2f15906eadde4b2794e5fe to your computer and use it in GitHub Desktop.
Save benbenbenbenbenben/79d9e0862f2f15906eadde4b2794e5fe to your computer and use it in GitHub Desktop.
static func convertDERtoRAW(_ signature: Data) throws -> Data {
// Check minimum length and sequence tag
guard signature.count >= 2, signature[0] == 0x30 else {
throw JWTSigningError.signatureConversionFailed
}
// Verify sequence length
let sequenceLength = Int(signature[1])
guard signature.count >= sequenceLength + 2 else {
throw JWTSigningError.signatureConversionFailed
}
var index = 2
// Extract R value
guard index < signature.count, signature[index] == 0x02 else {
throw JWTSigningError.signatureConversionFailed
}
index += 1
guard index < signature.count else {
throw JWTSigningError.signatureConversionFailed
}
let rLength = Int(signature[index])
index += 1
guard index + rLength <= signature.count else {
throw JWTSigningError.signatureConversionFailed
}
var rValue = signature[index..<(index + rLength)]
// Handle DER leading zero byte if present
if rValue.first == 0x00 {
rValue = rValue.dropFirst()
}
index += rLength
// Extract S value with same checks
guard index < signature.count, signature[index] == 0x02 else {
throw JWTSigningError.signatureConversionFailed
}
index += 1
guard index < signature.count else {
throw JWTSigningError.signatureConversionFailed
}
let sLength = Int(signature[index])
index += 1
guard index + sLength <= signature.count else {
throw JWTSigningError.signatureConversionFailed
}
var sValue = signature[index..<(index + sLength)]
// Handle DER leading zero byte if present
if sValue.first == 0x00 {
sValue = sValue.dropFirst()
}
// Create fixed-length 32-byte components
var rawSignature = Data(count: 64)
// Copy R value (right-aligned in first 32 bytes)
let rBytes = Array(rValue.suffix(min(32, rValue.count)))
let rStart = 32 - rBytes.count // Right align
rawSignature.replaceSubrange(rStart..<(rStart + rBytes.count), with: rBytes)
// Copy S value (right-aligned in second 32 bytes)
let sBytes = Array(sValue.suffix(min(32, sValue.count)))
let sStart = 64 - sBytes.count // Right align
rawSignature.replaceSubrange(sStart..<(sStart + sBytes.count), with: sBytes)
return rawSignature
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment