How to Load Rsa Private Key from File

Load RSA public key from file

Below is the relevant information from the link which Zaki provided.

Generate a 2048-bit RSA private key

$ openssl genrsa -out private_key.pem 2048

Convert private Key to PKCS#8 format (so Java can read it)

$ openssl pkcs8 -topk8 -inform PEM -outform DER -in private_key.pem -out private_key.der -nocrypt

Output public key portion in DER format (so Java can read it)

$ openssl rsa -in private_key.pem -pubout -outform DER -out public_key.der

Private key

import java.nio.file.*;
import java.security.*;
import java.security.spec.*;

public class PrivateKeyReader {

public static PrivateKey get(String filename)
throws Exception {

byte[] keyBytes = Files.readAllBytes(Paths.get(filename));

PKCS8EncodedKeySpec spec =
new PKCS8EncodedKeySpec(keyBytes);
KeyFactory kf = KeyFactory.getInstance("RSA");
return kf.generatePrivate(spec);
}
}

Public key

import java.nio.file.*;
import java.security.*;
import java.security.spec.*;

public class PublicKeyReader {

public static PublicKey get(String filename)
throws Exception {

byte[] keyBytes = Files.readAllBytes(Paths.get(filename));

X509EncodedKeySpec spec =
new X509EncodedKeySpec(keyBytes);
KeyFactory kf = KeyFactory.getInstance("RSA");
return kf.generatePublic(spec);
}
}

How to Load RSA Private Key From File

You need to convert your private key to PKCS8 format using following command:

openssl pkcs8 -topk8 -inform PEM -outform DER -in private_key_file  -nocrypt > pkcs8_key

After this your java program can read it.

How to read an RSA key from file

A combination of pem.Decode and x509.ParsePKCS1PrivateKey should do the trick:

package main

import (
"crypto/x509"
"encoding/pem"
"fmt"
)

func main() {
pemString := `-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQDLets8+7M+iAQAqN/5BVyCIjhTQ4cmXulL+gm3v0oGMWzLupUS
v8KPA+Tp7dgC/DZPfMLaNH1obBBhJ9DhS6RdS3AS3kzeFrdu8zFHLWF53DUBhS92
5dCAEuJpDnNizdEhxTfoHrhuCmz8l2nt1pe5eUK2XWgd08Uc93h5ij098wIDAQAB
AoGAHLaZeWGLSaen6O/rqxg2laZ+jEFbMO7zvOTruiIkL/uJfrY1kw+8RLIn+1q0
wLcWcuEIHgKKL9IP/aXAtAoYh1FBvRPLkovF1NZB0Je/+CSGka6wvc3TGdvppZJe
rKNcUvuOYLxkmLy4g9zuY5qrxFyhtIn2qZzXEtLaVOHzPQECQQDvN0mSajpU7dTB
w4jwx7IRXGSSx65c+AsHSc1Rj++9qtPC6WsFgAfFN2CEmqhMbEUVGPv/aPjdyWk9
pyLE9xR/AkEA2cGwyIunijE5v2rlZAD7C4vRgdcMyCf3uuPcgzFtsR6ZhyQSgLZ8
YRPuvwm4cdPJMmO3YwBfxT6XGuSc2k8MjQJBAI0+b8prvpV2+DCQa8L/pjxp+VhR
Xrq2GozrHrgR7NRokTB88hwFRJFF6U9iogy9wOx8HA7qxEbwLZuhm/4AhbECQC2a
d8h4Ht09E+f3nhTEc87mODkl7WJZpHL6V2sORfeq/eIkds+H6CJ4hy5w/bSw8tjf
sz9Di8sGIaUbLZI2rd0CQQCzlVwEtRtoNCyMJTTrkgUuNufLP19RZ5FpyXxBO5/u
QastnN77KfUwdj3SJt44U/uh1jAIv4oSLBr8HYUkbnI8
-----END RSA PRIVATE KEY-----`

block, _ := pem.Decode([]byte(pemString))
key, _ := x509.ParsePKCS1PrivateKey(block.Bytes)
fmt.Println(key.N)
}

If what you are sitting on is a PKCS#8 encoded key, instead you would do something like the following:

func main() {
pemString := `-----BEGIN PRIVATE KEY-----
MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAKhPSTDs4cpKfnMc
p86fCkpnuER7bGc+mGkhkw6bE+BnROfrDCFBSjrENLS5JcsenANQ1kYGt9iVW2fd
ZAWUdDoj+t7g6+fDpzY1BzPSUls421Dmu7joDPY8jSdMzFCeg7Lyj0I36bJJ7ooD
VPW6Q0XQcb8FfBiFPAKuY4elj/YDAgMBAAECgYBo2GMWmCmbM0aL/KjH/KiTawMN
nfkMY6DbtK9/5LjADHSPKAt5V8ueygSvI7rYSiwToLKqEptJztiO3gnls/GmFzj1
V/QEvFs6Ux3b0hD2SGpGy1m6NWWoAFlMISRkNiAxo+AMdCi4I1hpk4+bHr9VO2Bv
V0zKFxmgn1R8qAR+4QJBANqKxJ/qJ5+lyPuDYf5s+gkZWjCLTC7hPxIJQByDLICw
iEnqcn0n9Gslk5ngJIGQcKBXIp5i0jWSdKN/hLxwgHECQQDFKGmo8niLzEJ5sa1r
spww8Hc2aJM0pBwceshT8ZgVPnpgmITU1ENsKpJ+y1RTjZD6N0aj9gS9UB/UXdTr
HBezAkEAqkDRTYOtusH9AXQpM3zSjaQijw72Gs9/wx1RxOSsFtVwV6U97CLkV1S+
2HG1/vn3w/IeFiYGfZXLKFR/pA5BAQJAbFeu6IaGM9yFUzaOZDZ8mnAqMp349t6Q
DB5045xJxLLWsSpfJE2Y12H1qvO1XUzYNIgXq5ZQOHBFbYA6txBy/QJBAKDRQN47
6YClq9652X+1lYIY/h8MxKiXpVZVncXRgY6pbj4pmWEAM88jra9Wq6R77ocyECzi
XCqi18A/sl6ymWc=
-----END PRIVATE KEY-----`

block, _ := pem.Decode([]byte(pemString))
parseResult, _ := x509.ParsePKCS8PrivateKey(block.Bytes)
key := parseResult.(*rsa.PrivateKey)
fmt.Println(key.N)
}

How to read a rsa public key file in java?

Try this method:

 /**
* reads a public key from a file
* @param filename name of the file to read
* @param algorithm is usually RSA
* @return the read public key
* @throws Exception
*/
public PublicKey getPemPublicKey(String filename, String algorithm) throws Exception {
File f = new File(filename);
FileInputStream fis = new FileInputStream(f);
DataInputStream dis = new DataInputStream(fis);
byte[] keyBytes = new byte[(int) f.length()];
dis.readFully(keyBytes);
dis.close();

String temp = new String(keyBytes);
String publicKeyPEM = temp.replace("-----BEGIN PUBLIC KEY-----\n", "");
publicKeyPEM = publicKeyPEM.replace("-----END PUBLIC KEY-----", "");

BASE64Decoder b64 = new BASE64Decoder();
byte[] decoded = b64.decodeBuffer(publicKeyPEM);

X509EncodedKeySpec spec = new X509EncodedKeySpec(decoded);
KeyFactory kf = KeyFactory.getInstance(algorithm);
return kf.generatePublic(spec);
}

source: Load RSA public key from file

how to load Private Key from .key file

I hope this will help you to generate the token.
keep the .key or .der file into classpath src/main/resources.

public class JWTClientService {

public String generateJWTToken(ProjectConfig jwtConfig) {
return Jwts.builder()
.setSubject(jwtConfig.getSubject())
.setIssuer(jwtConfig.getIssuer())
.setExpiration(getExpiryDate(jwtConfig.getTokenExpiryUnit(), jwtConfig.getTokenExpiryFrequency()))
.setAudience(jwtConfig.getAudience())
.claim(jwtConfig.getClaimKey(), Boolean.valueOf(jwtConfig.getClaimValue()))
.signWith(SignatureAlgorithm.RS512, privateKey(jwtConfig))
.compact();
}

private Date getExpiryDate(String tokenExp, String tokenExpFreq) {
Calendar calendar = Calendar.getInstance();
int expiry = Integer.parseInt(tokenExp);
switch (tokenExpFreq.toLowerCase()) {

case "second": {
calendar.add(Calendar.SECOND, expiry);
break;
}
case "minute": {
calendar.add(Calendar.MINUTE, expiry);
break;
}
case "hour": {
calendar.add(Calendar.HOUR, expiry);
break;
}
case "day": {
calendar.add(Calendar.DATE, expiry);
break;
}
case "month": {
calendar.add(Calendar.MONTH, expiry);
break;
}
default: {
calendar.add(Calendar.HOUR, expiry);
break;
}
}
return calendar.getTime();
}

private PrivateKey privateKey(ProjectConfig jwtConfig) {
PrivateKey privateKey = null;
try {
InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(jwtConfig.getKeyPath());
ByteArrayOutputStream byteOutputStream = new ByteArrayOutputStream();
assert inputStream != null;
IOUtils.copy(inputStream, byteOutputStream);
byte[] privKeyByteArray = byteOutputStream.toByteArray();
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privKeyByteArray);

KeyFactory keyFactory = KeyFactory.getInstance(jwtConfig.getKeyAlgorithm());

privateKey = keyFactory.generatePrivate(keySpec);
} catch (Exception ex) {
throw new RuntimeException("Unable to generate private key..." + ex.getMessage());
}
return privateKey;
}

}

Find the Project config class:

 @JsonInclude(JsonInclude.Include.NON_NULL)
public class ProjectConfig {
private String clientId;
private String clientSecret;
private String jwtTokenUrl;
private String keyAlgorithm;
private String keyPath;
private String subject;
private String issuer;
private String audience;
private String claimKey;
private String claimValue;
private String tokenExpiryFrequency;
private String tokenExpiryUnit;

public String getClientId() {
return clientId;
}

public void setClientId(String clientId) {
this.clientId = clientId;
}

public String getClientSecret() {
return clientSecret;
}

public void setClientSecret(String clientSecret) {
this.clientSecret = clientSecret;
}

public String getJwtTokenUrl() {
return jwtTokenUrl;
}

public void setJwtTokenUrl(String jwtTokenUrl) {
this.jwtTokenUrl = jwtTokenUrl;
}

public String getKeyAlgorithm() {
return keyAlgorithm;
}

public void setKeyAlgorithm(String keyAlgorithm) {
this.keyAlgorithm = keyAlgorithm;
}

public String getKeyPath() {
return keyPath;
}

public void setKeyPath(String keyPath) {
this.keyPath = keyPath;
}

public String getSubject() {
return subject;
}

public void setSubject(String subject) {
this.subject = subject;
}

public String getIssuer() {
return issuer;
}

public void setIssuer(String issuer) {
this.issuer = issuer;
}

public String getAudience() {
return audience;
}

public void setAudience(String audience) {
this.audience = audience;
}

public String getClaimKey() {
return claimKey;
}

public void setClaimKey(String claimKey) {
this.claimKey = claimKey;
}

public String getClaimValue() {
return claimValue;
}

public void setClaimValue(String claimValue) {
this.claimValue = claimValue;
}

public String getTokenExpiryFrequency() {
return tokenExpiryFrequency;
}

public void setTokenExpiryFrequency(String tokenExpiryFrequency) {
this.tokenExpiryFrequency = tokenExpiryFrequency;
}

public String getTokenExpiryUnit() {
return tokenExpiryUnit;
}

public void setTokenExpiryUnit(String tokenExpiryUnit) {
this.tokenExpiryUnit = tokenExpiryUnit;
}
}

Main Class :

public class TokenApplication {
static ObjectMapper objectMapper = new ObjectMapper()
.configure(JsonParser.Feature.AUTO_CLOSE_SOURCE, true);

public static void main(String[] args) {
ProjectConfig projectConfig = loadConfiguration("application-stg.properties");

if (args.length > 0 && args[0].equals("PROD")) {
projectConfig = loadConfiguration("application-prod.properties");
}
try {
JWTTokenService jwtTokenService = new JWTTokenService();
System.out.println(jwtTokenService.getJwtToken(projectConfig).getAccessToken());
System.exit(JobStatus.SUCCESS.getCode());
} catch (Exception ex) {
System.exit(JobStatus.PROCESS_FAILED.getCode());
}

}

private static ProjectConfig loadConfiguration(String filePath) {
try (InputStream input = TokenApplication.class.getClassLoader().getResourceAsStream(filePath)) {
Properties props = new Properties();
props.load(input);
return objectMapper.convertValue(new HashMap(props), ProjectConfig.class);
} catch (Exception ex) {
throw new RuntimeException("Not able to load configuration" + ex.getMessage());
}
}

}

application-stg.properties

keyAlgorithm=RSA
keyPath=private-stage.der
subject=
issuer=
audience=
claimKey=
claimValue=true
tokenExpiryFrequency=DAY
tokenExpiryUnit=1
clientId=
clientSecret=
jwtTokenUrl=

Load RSA private key from a PEM encoded private key

The key is PEM encoded. You need to strip the PEM header and footer, then convert from Base64 back to DER/BER, and finally use Crypto++'s BERDecodePrivateKey.

There's some reading on the subject at the Crypto++ wiki under Keys and Formats. Below is the code to perform the conversion (I don't believe Stack Overflow has a working example of it in Crypto++).

string RSA_PRIV_KEY =
"-----BEGIN RSA PRIVATE KEY-----\n"
"MIIBOgIBAAJBAK8Q+ToR4tWGshaKYRHKJ3ZmMUF6jjwCS/u1A8v1tFbQiVpBlxYB\n"
"paNcT2ENEXBGdmWqr8VwSl0NBIKyq4p0rhsCAQMCQHS1+3wL7I5ZzA8G62Exb6RE\n"
"INZRtCgBh/0jV91OeDnfQUc07SE6vs31J8m7qw/rxeB3E9h6oGi9IVRebVO+9zsC\n"
"IQDWb//KAzrSOo0P0yktnY57UF9Q3Y26rulWI6LqpsxZDwIhAND/cmlg7rUz34Pf\n"
"SmM61lJEmMEjKp8RB/xgghzmCeI1AiEAjvVVMVd8jCcItTdwyRO0UjWU4JOz0cnw\n"
"5BfB8cSIO18CIQCLVPbw60nOIpUClNxCJzmMLbsrbMcUtgVS6wFomVvsIwIhAK+A\n"
"YqT6WwsMW2On5l9di+RPzhDT1QdGyTI5eFNS+GxY\n"
"-----END RSA PRIVATE KEY-----";

static string HEADER = "-----BEGIN RSA PRIVATE KEY-----";
static string FOOTER = "-----END RSA PRIVATE KEY-----";

size_t pos1, pos2;
pos1 = RSA_PRIV_KEY.find(HEADER);
if(pos1 == string::npos)
throw runtime_error("PEM header not found");

pos2 = RSA_PRIV_KEY.find(FOOTER, pos1+1);
if(pos2 == string::npos)
throw runtime_error("PEM footer not found");

// Start position and length
pos1 = pos1 + HEADER.length();
pos2 = pos2 - pos1;
string keystr = RSA_PRIV_KEY.substr(pos1, pos2);

// Base64 decode, place in a ByteQueue
ByteQueue queue;
Base64Decoder decoder;

decoder.Attach(new Redirector(queue));
decoder.Put((const byte*)keystr.data(), keystr.length());
decoder.MessageEnd();

// Write to file for inspection
FileSink fs("decoded-key.der");
queue.CopyTo(fs);
fs.MessageEnd();

try
{
CryptoPP::RSA::PrivateKey rsaPrivate;
rsaPrivate.BERDecodePrivateKey(queue, false /*paramsPresent*/, queue.MaxRetrievable());

// BERDecodePrivateKey is a void function. Here's the only check
// we have regarding the DER bytes consumed.
ASSERT(queue.IsEmpty());
}
catch (const Exception& ex)
{
cerr << ex.what() << endl;
exit (1);
}

After loading the key, you can validate it with:

AutoSeededRandomPool prng;
bool valid = rsaPrivate.Validate(prng, 3);
if(!valid)
cerr << "RSA private key is not valid" << endl;

And print it with:

cout << "N: " << rsaPrivate.GetModulus() << endl << endl;
cout << "E: " << rsaPrivate.GetPublicExponent() << endl << endl;
cout << "D: " << rsaPrivate.GetPrivateExponent() << endl << endl;

If the key is password protected, then Crypto++ cannot decode it. The library lacks the support to perform the decryption. In this case, you can convert it to BER/DER using the following OpenSSL command. Then you can use the key material with Crypto++.

openssl pkcs8 -nocrypt -in rsa-key.pem -inform PEM -topk8 -outform DER -out rsa-key.der

The sample program wrote the key to file with this:

FileSink fs("decoded-key.der");
queue.CopyTo(fs);
fs.MessageEnd();

The CopyTo leaves the bytes in the queue for use later. You can dump the file with an ASN.1 tool, like Gutmann's dumpasn1:

$ dumpasn1 decoded-key.der 
0 314: SEQUENCE {
4 1: INTEGER 0
7 65: INTEGER
: 00 AF 10 F9 3A 11 E2 D5 86 B2 16 8A 61 11 CA 27
: 76 66 31 41 7A 8E 3C 02 4B FB B5 03 CB F5 B4 56
: D0 89 5A 41 97 16 01 A5 A3 5C 4F 61 0D 11 70 46
: 76 65 AA AF C5 70 4A 5D 0D 04 82 B2 AB 8A 74 AE
: 1B
74 1: INTEGER 3
77 64: INTEGER
: 74 B5 FB 7C 0B EC 8E 59 CC 0F 06 EB 61 31 6F A4
: 44 20 D6 51 B4 28 01 87 FD 23 57 DD 4E 78 39 DF
: 41 47 34 ED 21 3A BE CD F5 27 C9 BB AB 0F EB C5
: E0 77 13 D8 7A A0 68 BD 21 54 5E 6D 53 BE F7 3B
143 33: INTEGER
: 00 D6 6F FF CA 03 3A D2 3A 8D 0F D3 29 2D 9D 8E
: 7B 50 5F 50 DD 8D BA AE E9 56 23 A2 EA A6 CC 59
: 0F
178 33: INTEGER
: 00 D0 FF 72 69 60 EE B5 33 DF 83 DF 4A 63 3A D6
: 52 44 98 C1 23 2A 9F 11 07 FC 60 82 1C E6 09 E2
: 35
213 33: INTEGER
: 00 8E F5 55 31 57 7C 8C 27 08 B5 37 70 C9 13 B4
: 52 35 94 E0 93 B3 D1 C9 F0 E4 17 C1 F1 C4 88 3B
: 5F
248 33: INTEGER
: 00 8B 54 F6 F0 EB 49 CE 22 95 02 94 DC 42 27 39
: 8C 2D BB 2B 6C C7 14 B6 05 52 EB 01 68 99 5B EC
: 23
283 33: INTEGER
: 00 AF 80 62 A4 FA 5B 0B 0C 5B 63 A7 E6 5F 5D 8B
: E4 4F CE 10 D3 D5 07 46 C9 32 39 78 53 52 F8 6C
: 58
: }

0 warnings, 0 errors.


Related Topics



Leave a reply



Submit