NdsForge.NET 1.0.1
Read, validate, edit, compare, and build Nintendo DS and DSi images from .NET
Loading...
Searching...
No Matches
NdsDsiRsaPublicKey.cs
1using System.Security.Cryptography;
2
3namespace NdsForge;
4
9public sealed class NdsDsiRsaPublicKey
10{
12 private readonly byte[] _modulus;
14 private readonly byte[] _exponent;
15
19 public NdsDsiRsaPublicKey(ReadOnlySpan<byte> modulus, ReadOnlySpan<byte> exponent)
20 {
21 if (modulus.Length != 128 || exponent.IsEmpty)
22 {
23 throw new ArgumentException("A DSi RSA key requires a 128-byte modulus and a non-empty exponent.");
24 }
25
26 _modulus = modulus.ToArray();
27 _exponent = exponent.ToArray();
28 }
29
33 public static NdsDsiRsaPublicKey FromRsa(RSA rsa)
34 {
35 ArgumentNullException.ThrowIfNull(rsa);
36 if (rsa.KeySize != 1024)
37 {
38 throw new ArgumentException("DSi header signatures require a 1024-bit RSA key.", nameof(rsa));
39 }
40
41 RSAParameters parameters = rsa.ExportParameters(includePrivateParameters: false);
42 return new(parameters.Modulus!, parameters.Exponent!);
43 }
44
46 public ReadOnlyMemory<byte> Modulus => _modulus.ToArray();
47
49 public ReadOnlyMemory<byte> Exponent => _exponent.ToArray();
50
55 public bool VerifyHeader(ReadOnlySpan<byte> signedHeader, ReadOnlySpan<byte> signature)
56 {
57 ValidateBuffers(signedHeader, signature);
58 using RSA rsa = RSA.Create();
59 rsa.ImportParameters(new() { Modulus = _modulus, Exponent = _exponent });
60#pragma warning disable CA5350, CA5387 // DSi headers mandate RSA-SHA1 with PKCS#1 v1.5; this type is format-specific.
61 return rsa.VerifyData(signedHeader, signature, HashAlgorithmName.SHA1, RSASignaturePadding.Pkcs1);
62#pragma warning restore CA5350, CA5387
63 }
64
68 private static void ValidateBuffers(ReadOnlySpan<byte> signedHeader, ReadOnlySpan<byte> signature)
69 {
70 if (signedHeader.Length != 0xE00 || signature.Length != 128)
71 {
72 throw new ArgumentException("DSi RSA verification requires a 0xE00-byte header prefix and 128-byte signature.");
73 }
74 }
75}
ReadOnlyMemory< byte > Exponent
Exports the conventional big-endian public exponent without exposing internal mutable storage.
static NdsDsiRsaPublicKey FromRsa(RSA rsa)
Snapshots the public portion of an existing RSA object after enforcing the DSi key size.
NdsDsiRsaPublicKey(ReadOnlySpan< byte > modulus, ReadOnlySpan< byte > exponent)
Copies raw parameters so trust configuration remains stable after caller buffers are reused or cleare...
ReadOnlyMemory< byte > Modulus
Exports the conventional big-endian modulus without exposing internal mutable storage.
bool VerifyHeader(ReadOnlySpan< byte > signedHeader, ReadOnlySpan< byte > signature)
Verifies the format-mandated RSA-SHA1 PKCS#1 v1.5 signature over a finalized header prefix.