java.lang.Object
net.i2p.crypto.SigUtil
Comprehensive utility class for I2P signing keys and digital signatures.
This class provides essential methods for converting between I2P's native key formats and standard Java cryptographic key representations, as well as utilities for signature encoding/decoding and key validation.
Key functionalities include:
- Conversion between I2P and Java key formats
- Support for DSA, ECDSA, EdDSA, and RSA algorithms
- ASN.1 signature encoding and decoding
- Key validation and rectification
Field Summary
FieldsModifier and TypeFieldDescriptionprivate static final Map<SigningPrivateKey, ECPrivateKey> Converted EC private keys, by signing key.private static final Map<SigningPublicKey, ECPublicKey> Converted EC public keys, by signing key.private static final Map<SigningPrivateKey, EdDSAPrivateKey> Converted EdDSA private keys, by signing key.private static final Map<SigningPublicKey, EdDSAPublicKey> Converted EdDSA public keys, by signing key.private static final intHow many times more EdDSA than DSA signatures are allowed.Constructor Summary
ConstructorsMethod Summary
Modifier and TypeMethodDescriptionstatic NativeBigInteger[]aSN1ToBigInteger(byte[] asn, int len) See above.private static byte[]aSN1ToSigBytes(byte[] asn, int len) Decode a DER-encoded signature into the fixed-width r then s bytes I2P signs.static voidClear all cached Java key conversions.(package private) static byte[]combine(BigInteger x, BigInteger y, int len) Combine two BigIntegers of nominal length = len / 2.private static ECPrivateKeyConvert an I2P EC private key to a Java ECPrivateKey without caching.private static ECPublicKeyConvert an I2P EC public key to a Java ECPublicKey without caching.private static EdDSAPrivateKeyConvert an I2P EdDSA or RedDSA private key to a Java EdDSAPrivateKey without caching.private static EdDSAPublicKeyConvert an I2P EdDSA public key to a Java EdDSAPublicKey without caching.static SigningPrivateKeyConvert a Java DSAPrivateKey to an I2P DSA private key.static SigningPublicKeyConvert a Java DSAPublicKey to an I2P DSA public key.static SigningPrivateKeyfromJavaKey(ECPrivateKey pk, SigType type) Convert a Java ECPrivateKey to an I2P SigningPrivateKey of the given type.static SigningPublicKeyfromJavaKey(ECPublicKey pk, SigType type) Convert a Java ECPublicKey to an I2P SigningPublicKey of the given type.static SigningPrivateKeyfromJavaKey(RSAPrivateKey pk, SigType type) Convert a Java RSAPrivateKey to an I2P RSA private key of the given type.static SigningPublicKeyfromJavaKey(RSAPublicKey pk, SigType type) Convert a Java RSAPublicKey to an I2P RSA public key of the given type.static SigningPrivateKeyUse if SigType is unknown.static SigningPrivateKeyfromJavaKey(PrivateKey pk, SigType type) Use if SigType is known.static SigningPublicKeyfromJavaKey(PublicKey pk) Use if SigType is unknown.static SigningPublicKeyfromJavaKey(PublicKey pk, SigType type) Use if SigType is known.static SigningPrivateKeyfromJavaKey(EdDSAPrivateKey pk, SigType type) Convert a Java EdDSAPrivateKey to an I2P SigningPrivateKey.static SigningPublicKeyfromJavaKey(EdDSAPublicKey pk, SigType type) Convert a Java EdDSAPublicKey to an I2P SigningPublicKey.static SignaturefromJavaSig(byte[] asn, SigType type) Convert a Java ASN.1 signature byte array to an I2P Signature.private static byte[]Read the whole file, capped at 16 KB.static PrivateKeyimportJavaPrivateKey(File file, SigType type) Import a Java PKCS8-encoded private key from a file.static PublicKeyimportJavaPublicKey(File file, SigType type) Import a Java X.509-encoded public key from a file.static intintToASN1(byte[] d, int idx, int val) Output an length or integer value in ASN.1 Does NOT output the tag e.g.static byte[]rectify(BigInteger bi, int len) Convert a BigInteger to a fixed-length byte array, trimming or zero-padding as needed.private static byte[]sigBytesToASN1(byte[] sig) Encode raw signature bytes (r || s) into ASN.1 DER SEQUENCE format.static byte[]private static NativeBigInteger[]split(byte[] b) Split a byte array into two BigIntegers.static DSAPrivateKeyConvert an I2P DSA private key to a Java DSAPrivateKey.static DSAPublicKeyConvert an I2P DSA public key to a Java DSAPublicKey.static ECPrivateKeyConvert an I2P EC private key to a Java ECPrivateKey, with caching.static ECPublicKeyConvert an I2P EC public key to a Java ECPublicKey, with caching.static EdDSAPrivateKeyConvert an I2P EdDSA private key to a Java EdDSAPrivateKey, with caching.static EdDSAPublicKeyConvert an I2P EdDSA public key to a Java EdDSAPublicKey, with caching.static PrivateKeyConvert an I2P SigningPrivateKey to a Java PrivateKey, dispatching by algorithm.static PublicKeyConvert an I2P SigningPublicKey to a Java PublicKey, dispatching by algorithm.static RSAPrivateKeyConvert an I2P RSA private key to a Java RSAPrivateKey.static RSAPublicKeyPrefer toJavaKey(SigningPublicKey) for type-generic conversion.static byte[]Convert an I2P Signature to a Java ASN.1 signature byte array.
Field Details
FACTOR
private static final int FACTORHow many times more EdDSA than DSA signatures are allowed._ECPubkeyCache
Converted EC public keys, by signing key._ECPrivkeyCache
Converted EC private keys, by signing key._EdPubkeyCache
Converted EdDSA public keys, by signing key._EdPrivkeyCache
Converted EdDSA private keys, by signing key.
Constructor Details
SigUtil
private SigUtil()Utility class, not intended for instantiation.
Method Details
toJavaKey
Convert an I2P SigningPublicKey to a Java PublicKey, dispatching by algorithm.- Parameters:
pk- non-null- Returns:
- Java PublicKey (DSA, EC, EdDSA, or RSA)
- Throws:
GeneralSecurityException- if conversion fails
toJavaKey
Convert an I2P SigningPrivateKey to a Java PrivateKey, dispatching by algorithm.- Parameters:
pk- non-null- Returns:
- Java PrivateKey (DSA, EC, EdDSA, or RSA)
- Throws:
GeneralSecurityException- if conversion fails
fromJavaKey
Use if SigType is unknown. For efficiency, use fromJavakey(pk, type) if type is known.- Parameters:
pk- JAVA key!- Returns:
- the I2P signing public key
- Throws:
InvalidKeyException- on unknown typeGeneralSecurityException
fromJavaKey
public static SigningPublicKey fromJavaKey(PublicKey pk, SigType type) throws GeneralSecurityException Use if SigType is known.- Parameters:
pk- JAVA key!type- the I2P signature type naming the base algorithm to convert with- Returns:
- I2P public key
- Throws:
GeneralSecurityException- if the JAVA key does not match the base algorithm of the type, or the type names an unknown algorithm
fromJavaKey
Use if SigType is unknown. For efficiency, use fromJavakey(pk, type) if type is known.- Parameters:
pk- JAVA key!- Returns:
- the I2P signing private key
- Throws:
InvalidKeyException- on unknown typeGeneralSecurityException
fromJavaKey
public static SigningPrivateKey fromJavaKey(PrivateKey pk, SigType type) throws GeneralSecurityException Use if SigType is known.- Parameters:
pk- JAVA key!type- the I2P signature type naming the base algorithm to convert with- Returns:
- I2P private key
- Throws:
GeneralSecurityException- if the JAVA key does not match the base algorithm of the type, or the type names an unknown algorithm
toJavaECKey
Convert an I2P EC public key to a Java ECPublicKey, with caching.- Parameters:
pk- non-null- Returns:
- Java ECPublicKey
- Throws:
GeneralSecurityException- if conversion fails
toJavaECKey
Convert an I2P EC private key to a Java ECPrivateKey, with caching.- Parameters:
pk- non-null- Returns:
- Java ECPrivateKey
- Throws:
GeneralSecurityException- if conversion fails
cvtToJavaECKey
Convert an I2P EC public key to a Java ECPublicKey without caching. Splits the key data into affine x and y coordinates.- Parameters:
pk- non-null- Returns:
- Java ECPublicKey
- Throws:
GeneralSecurityException- if conversion fails
cvtToJavaECKey
Convert an I2P EC private key to a Java ECPrivateKey without caching. Extracts the scalar s from the key data.- Parameters:
pk- non-null- Returns:
- Java ECPrivateKey
- Throws:
GeneralSecurityException- if conversion fails
fromJavaKey
public static SigningPublicKey fromJavaKey(ECPublicKey pk, SigType type) throws GeneralSecurityException Convert a Java ECPublicKey to an I2P SigningPublicKey of the given type.- Parameters:
pk- non-nulltype- the I2P signature type- Returns:
- I2P public key
- Throws:
GeneralSecurityException- if conversion fails
fromJavaKey
public static SigningPrivateKey fromJavaKey(ECPrivateKey pk, SigType type) throws GeneralSecurityException Convert a Java ECPrivateKey to an I2P SigningPrivateKey of the given type.- Parameters:
pk- non-nulltype- the I2P signature type- Returns:
- I2P private key
- Throws:
GeneralSecurityException- if conversion fails
toJavaEdDSAKey
Convert an I2P EdDSA public key to a Java EdDSAPublicKey, with caching.- Parameters:
pk- non-null- Returns:
- Java EdDSAPublicKey
- Throws:
GeneralSecurityException- if the I2P key bytes cannot be converted to a Java EdDSA key
toJavaEdDSAKey
Convert an I2P EdDSA private key to a Java EdDSAPrivateKey, with caching.- Parameters:
pk- non-null- Returns:
- Java EdDSAPrivateKey
- Throws:
GeneralSecurityException- if the I2P key bytes cannot be converted to a Java EdDSA key
cvtToJavaEdDSAKey
private static EdDSAPublicKey cvtToJavaEdDSAKey(SigningPublicKey pk) throws GeneralSecurityException Convert an I2P EdDSA public key to a Java EdDSAPublicKey without caching.- Parameters:
pk- non-null- Returns:
- Java EdDSAPublicKey
- Throws:
GeneralSecurityException- as InvalidKeyException if the key bytes do not form a valid key for the type
cvtToJavaEdDSAKey
private static EdDSAPrivateKey cvtToJavaEdDSAKey(SigningPrivateKey pk) throws GeneralSecurityException Convert an I2P EdDSA or RedDSA private key to a Java EdDSAPrivateKey without caching.- Parameters:
pk- non-null- Returns:
- Java EdDSAPrivateKey
- Throws:
GeneralSecurityException- as InvalidKeyException if the type is neither EdDSA nor RedDSA, or the key bytes are invalid
fromJavaKey
Convert a Java EdDSAPublicKey to an I2P SigningPublicKey.- Parameters:
pk- non-nulltype- the I2P signature type- Returns:
- I2P public key
fromJavaKey
public static SigningPrivateKey fromJavaKey(EdDSAPrivateKey pk, SigType type) throws GeneralSecurityException Convert a Java EdDSAPrivateKey to an I2P SigningPrivateKey. Handles EdDSA (seed-based) and RedDSA (private scalar) key types.- Parameters:
pk- non-nulltype- the I2P signature type- Returns:
- I2P private key
- Throws:
GeneralSecurityException- if the key type names neither an EdDSA seed nor a RedDSA private scalar
toJavaDSAKey
Convert an I2P DSA public key to a Java DSAPublicKey.- Parameters:
pk- non-null- Returns:
- Java DSAPublicKey
- Throws:
GeneralSecurityException- if conversion fails
toJavaDSAKey
Convert an I2P DSA private key to a Java DSAPrivateKey.- Parameters:
pk- non-null- Returns:
- Java DSAPrivateKey
- Throws:
GeneralSecurityException- if conversion fails
fromJavaKey
Convert a Java DSAPublicKey to an I2P DSA public key.- Parameters:
pk- non-null- Returns:
- I2P DSA public key
- Throws:
GeneralSecurityException- if conversion fails
fromJavaKey
Convert a Java DSAPrivateKey to an I2P DSA private key.- Parameters:
pk- non-null- Returns:
- I2P DSA private key
- Throws:
GeneralSecurityException- if conversion fails
toJavaRSAKey
Prefer toJavaKey(SigningPublicKey) for type-generic conversion.- Parameters:
pk- non-null- Returns:
- Java RSA public key
- Throws:
GeneralSecurityException- if conversion fails
toJavaRSAKey
Convert an I2P RSA private key to a Java RSAPrivateKey. As of 0.9.31, if pk is a RSASigningPrivateCrtKey, returns a RSAPrivateCrtKey.- Parameters:
pk- non-null- Returns:
- Java RSAPrivateKey
- Throws:
GeneralSecurityException- if conversion fails
fromJavaKey
public static SigningPublicKey fromJavaKey(RSAPublicKey pk, SigType type) throws GeneralSecurityException Convert a Java RSAPublicKey to an I2P RSA public key of the given type.- Parameters:
pk- non-nulltype- the I2P signature type- Returns:
- I2P RSA public key
- Throws:
GeneralSecurityException- if conversion fails
fromJavaKey
public static SigningPrivateKey fromJavaKey(RSAPrivateKey pk, SigType type) throws GeneralSecurityException Convert a Java RSAPrivateKey to an I2P RSA private key of the given type. As of 0.9.31, if pk is a RSAPrivateCrtKey, returns a RSASigningPrivateCrtKey.- Parameters:
pk- non-nulltype- the I2P signature type- Returns:
- I2P RSA private key
- Throws:
GeneralSecurityException- if conversion fails
toJavaSig
Convert an I2P Signature to a Java ASN.1 signature byte array. RSA and EdDSA signatures are passed through unchanged.- Parameters:
sig- non-null- Returns:
- ASN.1 DER-encoded signature bytes (or raw for RSA/EdDSA)
fromJavaSig
Convert a Java ASN.1 signature byte array to an I2P Signature. RSA and EdDSA signatures are passed through unchanged.- Parameters:
asn- ASN.1 DER-encoded signature bytes (or raw for RSA/EdDSA)type- the I2P signature type- Returns:
- an I2P Signature with the given type
- Throws:
SignatureException- if ASN.1 decoding fails
importJavaPublicKey
public static PublicKey importJavaPublicKey(File file, SigType type) throws GeneralSecurityException, IOException Import a Java X.509-encoded public key from a file.- Parameters:
file- non-null, containing X.509 encoded key datatype- the I2P signature type- Returns:
- Java PublicKey
- Throws:
GeneralSecurityException- if key conversion failsIOException- if file reading fails
importJavaPrivateKey
public static PrivateKey importJavaPrivateKey(File file, SigType type) throws GeneralSecurityException, IOException Import a Java PKCS8-encoded private key from a file.- Parameters:
file- non-null, containing PKCS8 encoded key datatype- the I2P signature type- Returns:
- Java PrivateKey
- Throws:
GeneralSecurityException- if key conversion failsIOException- if file reading fails
getData
Read the whole file, capped at 16 KB.- Parameters:
file- the file to read- Returns:
- the bytes read, never more than 16 KB
- Throws:
IOException- if the file cannot be read, or holds more than 16 KB
split
Split a byte array into two BigIntegers.- Parameters:
b- length must be even- Returns:
- array of two BigIntegers
combine
Combine two BigIntegers of nominal length = len / 2.- Parameters:
x- non-negative first valuey- non-negative second valuelen- total output length (must be even)- Returns:
- array of exactly len bytes
- Throws:
InvalidKeyException- if length is odd or either value is too large
rectify
Convert a BigInteger to a fixed-length byte array, trimming or zero-padding as needed.- Parameters:
bi- non-negativelen- desired output length- Returns:
- array of exactly len bytes
- Throws:
InvalidKeyException- if the value is negative or too large to fit
sigBytesToASN1
private static byte[] sigBytesToASN1(byte[] sig) Encode raw signature bytes (r || s) into ASN.1 DER SEQUENCE format.Convert to BigInteger and back so we have the minimum length representation, as required. r and s are always non-negative.
Only supports sigs up to about 252 bytes. See code to fix BER encoding for this before you add a SigType with bigger signatures.
- Parameters:
sig- raw r||s bytes, length must be even- Returns:
- ASN.1 DER-encoded SEQUENCE { r INTEGER, s INTEGER }
- Throws:
IllegalArgumentException- if length is odd or encoded size exceeds limits
sigBytesToASN1
Encode twoBigIntegervalues (r,s) into an ASN.1 DERSEQUENCEof twoINTEGERvalues.randsare always non-negative.Only supports sigs up to about 65530 bytes. See code to fix BER encoding for this before you add a SigType with bigger signatures.
The output is an ASN.1 DER SEQUENCE of two INTEGER values,
rands, in that order:SEQUENCE ::= { r INTEGER, s INTEGER } 30 -- tag indicating SEQUENCE xx - length in octets 02 -- tag indicating INTEGER xx - length in octets xxxxxx - value- Parameters:
r- non-negatives- non-negative- Returns:
- ASN.1 DER-encoded SEQUENCE { r INTEGER, s INTEGER }
- Throws:
IllegalArgumentException- if too big- See Also:
intToASN1
public static int intToASN1(byte[] d, int idx, int val) Output an length or integer value in ASN.1 Does NOT output the tag e.g. 0x02 / 0x30.- Parameters:
d- the destination buffer to write the ASN.1 form intoidx- the offset in d to start writing at, advanced past what is writtenval- 0-65535- Returns:
- the new index
aSN1ToSigBytes
Decode a DER-encoded signature into the fixed-width r then s bytes I2P signs. Only supports sigs up to about 65530 bytes. See code to fix BER encoding for bigger than that.- Parameters:
asn- the DER-encoded signature to decodelen- must be even, twice the nominal length of each BigInteger- Returns:
- a byte array of len bytes; call
split(byte[])on the result to get the two BigIntegers - Throws:
SignatureException- if the input is not an ASN.1 sequence of two integers
aSN1ToBigInteger
See above. Only supports sigs up to about 65530 bytes. See code to fix BER encoding for bigger than that.- Parameters:
asn- the ASN.1 encoded signature or public key to decodelen- the nominal length of each BigInteger the encoding holds- Returns:
- the R and S integers, each of
lenbytes - Throws:
SignatureException- if the encoding does not hold the two integers of the expected length
clearCaches
public static void clearCaches()Clear all cached Java key conversions. Should be called when key types or configurations change.