How can I produce a valid Private Key (in any format) from the primes? - cryptography

I have the necessary components to build the private/public RSA key: N, E, D, P, & Q. I can derive the other values for the CRT if needed. How can I use these parameters to produce a valid Private/Public key in DER, PEM, or PKCS#7? It doesn't matter which to me as I can convert between them. I'm looking for a tool, library, script, or program that supports assigning these values and writing out a valid file, so I don't have to read hundreds of pages on ASN.1. Every tool I've looked at doesn't expose this use case in the API.

If you are using Java, there is the RSAPrivateKeySpec class, which takes BigInteger arguments of modulus and exponent. There are subclasses which take instead of N the P and Q primes (for more efficiency). You can then use a KeyFactory to convert this object to a Key, and then to some EncodedKeySpec class like PKCS8EncodedKeySpec or X509EncodedKeySpec.

You should be able to use OpenSSL (the library).
BIGNUM is described here. There are many functions to create a BIGNUM out of your input (depending on format). BN_bin2bn is probably the simplest, but hexadecimal or decimal input is also supported.
RSA is a structure that contains BIGNUMs. It's described here. You can initialise it yourself (directly).
You can then write the RSA structure using one of the PEM functions (described here). For example, PEM_write_RSAPrivateKey writes a PEM file containing a private key (you can also encrypt it, if you want to).
I'm not aware of any tool that does all of the above. Also, ASN.1 isn't so bad (a public/private key is pretty much a SEQUENCE of INTEGERs).

Related

Java/Kotlin Output Ed25519 keypair as both JCE KeyPair instance and in OpenSSH format

I'm generating Ed25519 key pairs in my Kotlin app using the BouncyCastle library and have two requirements that are easy to implement in isolation, but seemingly difficult to do in tandem:
Provide the key pair as a JCE KeyPair instance for use with a third-party SSH library
Provide the public key in OpenSSH .pub format for the user to copy and paste into a git repository provider such as GitHub (i.e. ssh-ed25519 <encoded key> <comment>)
I have two options for generating the keys using BouncyCastle, each makes only one of these requirements easy.
Generate directly using BouncyCastle generator
val generator = Ed25519KeyPairGenerator()
generator.init(Ed25519KeyGenerationParameters(SecureRandom()))
val pair = generator.generateKeyPair()
This gives me a key containing Ed25519PublicKeyParameters, which makes it super easy to get the OpenSSH .pub format using OpenSSHPublicKeyUtil provided by BouncyCastle:
"ssh-ed25519 " + toBase64(OpenSSHPublicKeyUtil.encodePublicKey(publicKey))
...but there is no obvious way to get to a JCE KeyPair from here. The BouncyCastle JCE implementation seems to use BCEdDSAPublicKey and BCEdDSAPrivateKey as wrapper classes for exactly this purpose, but their constructors are package-private.
Generate using BouncyCastle as a JCE security provider
Security.addProvider(BouncyCastleProvider())
val keyPairGenerator: KeyPairGenerator = KeyPairGenerator.getInstance(EdDSAParameterSpec.Ed25519, BouncyCastleProvider.PROVIDER_NAME)
keyPairGenerator.initialize(EdDSAParameterSpec(EdDSAParameterSpec.Ed25519), SecureRandom())
val pair = keyPairGenerator.generateKeyPair()
This gives me the JCE KeyPair I'm looking for, but no obvious way to convert it to OpenSSH .pub format. The answers in this RSA-specific question all only support DSA/RSA, or suggest libraries that also don't seem to be able to handle the Ed25519 keys. I have tried:
Apache SSHD
SSHJ
Jsch
What I think I need
Any one of:
A way to convert from BouncyCastle's AsymmetricCipherKeyPair to a JCE KeyPair
A way to get a Ed25519PublicKeyParameters instance from a BCEdDSAPublicKey wrapper so I can use BouncyCastle's OpenSSH utility method
Another way to output a BouncyCastle generated Ed25519 public key from a KeyPair in OpenSSH format
Another way/library to generate an Ed25519 keypair that will support my two requirements
Hack using reflection (wrapped into getter of extension property), following way #2 (get a Ed25519PublicKeyParameters instance from a BCEdDSAPublicKey):
val BCEdDSAPublicKey.pubKey
get() = BCEdDSAPublicKey::class.declaredMemberProperties
.find { it.returnType.javaType == AsymmetricKeyParameter::class.java }!!
.apply { isAccessible = true }
.get(this) as AsymmetricKeyParameter

Get key parameters from imported Elliptic Curve key in ASN.1 format

I need to write code that gets as input Elliptic Curve key in ASN.1 format.
The input byte array is next:
308187020100301306072A8648CE3D020106082A8648CE3D030107046D306B0201010420E699203AC5BCFE36402EBD0AC9E8E21CC6FAD5828A61297EA747468FFF4DBB20A144034200047E05188A03EA81E853B9F6AC5F20DCA1A1CA828FD7CD5D92161FB2120C35EAC52EAB079ED01A510123057C322DDFF95E239D6063055BC90858D161D71DE707F8
Online parser shows me the next structure:
To use key as I want I need to get public value X, public value Y and private value from this structure, at least I think so. But I do not know how.
I have searched information about OBJECT IDENTIFIER 1.2.840.10045.2.1 and OBJECT IDENTIFIER 1.2.840.10045.3.1.7. I've found this document. But there is no description of fields of ASN.1 structure.
How can I get required parameters from imported data?
It's commonly known as a PKCS#8 structure, which is the "Private-Key Information Syntax Specification". It only contains the unencrypted part of a PKCS#8 private key.
So this is in PKCS#8:
PrivateKeyInfo ::= SEQUENCE {
version Version,
privateKeyAlgorithm AlgorithmIdentifier {{PrivateKeyAlgorithms}},
privateKey PrivateKey,
attributes [0] Attributes OPTIONAL
}
The AlgorithmIdentifier is taken from PKCS#5
AlgorithmIdentifier { ALGORITHM-IDENTIFIER:InfoObjectSet } ::= SEQUENCE {
algorithm ALGORITHM-IDENTIFIER.&id({InfoObjectSet}),
parameters ALGORITHM-IDENTIFIER.&Type({InfoObjectSet}
{#algorithm}) OPTIONAL
}
The Elliptic Curve Private Key structure:
ECPrivateKey ::= SEQUENCE {
version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1),
privateKey OCTET STRING,
parameters [0] ECParameters {{ NamedCurve }} OPTIONAL,
publicKey [1] BIT STRING OPTIONAL
}
Oh, and encoded in DER, the Distinguished Encoding Rules (study version) - you may not be able to rule out BER completely, which is a more loosely defined and therefore harder to parse structure). PKCS#8 defines BER unfortunately.
Oh, yeah, the public key is in uncompressed point format. Don't forget to strip away the 00 from the bit string.
Happy parsing.

Thrift go support of map with struct value as key

I experimented golang generation with Thrift 0.9.1, for example,
thrift definition,
struct AppIdLeveledHashKeyTimeKeyHour {
1: required i32 appId
2: required LeveledHashKey leveledHashKey
3: required TimeKeyHour timeKeyHour
}
typedef map<AppIdLeveledHashKeyTimeKeyHour, ...sth else...> EventSliceShardIdValue
in the generated code, EventSliceShardIdValue would be,
type EventSliceShardIdValue map[*AppIdLeveledHashKeyTimeKeyHour]EventSliceAppIdLeveledHashKeyTimeKeyHourValue
you can find the key part is a pointer which represents memory address. In golang a pointer as map key (instead of a value, or hash of the obj) is useless in most cases. To use a combination of some fields as map key, the definition should use a value type like
map[AppIdLeveledHashKeyTimeKeyHour]EventSliceAppIdLeveledHashKeyTimeKeyHourValue
Is it a problem of Thrift's go support (or I misused sth)? Any workaround to solve this problem in thrift?
Structs (without pointers) can only be used as map keys under certain limited circumstances (they must be comparable per http://golang.org/ref/spec#Comparison_operators); it's possible that AppIdLeveledHashKeyTimeKeyHour doesn't fit this definition, so it's not actually possible to build a map without using a pointer for the key.

Generating a key

I am writing an encryption application that requires a 64 bit key. I am currently using the following code to automatically generate a key.
Function GenerateKey() As String
' Create an instance of a symmetric algorithm. The key and the IV are generated automatically.
Dim desCrypto As DESCryptoServiceProvider = DESCryptoServiceProvider.Create()
' Use the automatically generated key for encryption.
Return ASCIIEncoding.ASCII.GetString(desCrypto.Key)
End Function
I am wanting the user to create their own key. Can I convert a user defined password (a string) into a 64 bit key that can be used?
The answer depends on how secure you want it to be, I'm no security expert so I wouldn't give advice on it.
I did see this though: http://msdn.microsoft.com/en-us/library/system.security.cryptography.rfc2898derivebytes.aspx It can be used to derives bytes from a string key and salt in the way Jodrell eluded to, and would be far better than rolling yor own.
The other constructor that might be suited after that stage is detailed here: http://msdn.microsoft.com/en-us/library/51cy2e75.aspx
I'm sure if you searched for that on the web you could find examples of how to use it.

Is there anything like SHA1CryptoServiceProvider (Which is C#) in Objective-C?

I am trying to create a serial number checker in an app that I am writing, and it uses cryptography to encode the name and entered number against what it actually should be. I am familiar with the SHA1CryptoServiceProvider used in C#, but is there anything like this in Objective-C?
Here is sample code from C# that I want to convert to Objective-C:
string license = txtnLicense.Text;
SHA1CryptoServiceProvider provider = new SHA1CryptoServiceProvider();
string finalLicense = BitConverter.ToString(provider.ComputeHash(bytes));
bool isGood = (BitConverter.ToString(provider.ComputeHash(bytes)).Replace("-", "") == license.Replace("-", ""));
Mac OS X comes with an easy-to-use encryption and hashing library built-in called CommonCrypto. You don't have to link against anything special to use it. See the headers in /usr/include/CommonCrypto for its interface and CC_SHA1(3cc) for docs.
using openssl for license keys shows how to use SHA1. It may be a good start.