blob: 4b816ed591db1282dc5984858843a8f9bcd54800 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.cn.lang.security;
import org.apache.fineract.cn.lang.DateConverter;
import java.math.BigInteger;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.RSAPrivateKeySpec;
import java.security.spec.RSAPublicKeySpec;
import java.time.Clock;
import java.time.LocalDateTime;
@SuppressWarnings({"WeakerAccess", "unused"})
public final class RsaKeyPairFactory {
private RsaKeyPairFactory() {
}
public static KeyPairHolder createKeyPair() {
try {
final KeyFactory keyFactory = KeyFactory.getInstance("RSA");
final KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(2048);
final KeyPair keyPair = keyPairGenerator.genKeyPair();
final RSAPublicKeySpec rsaPublicKeySpec =
keyFactory.getKeySpec(keyPair.getPublic(), RSAPublicKeySpec.class);
final RSAPrivateKeySpec rsaPrivateKeySpec =
keyFactory.getKeySpec(keyPair.getPrivate(), RSAPrivateKeySpec.class);
final String keyTimestamp = createKeyTimestampNow();
final RSAPublicKey publicKey = (RSAPublicKey) keyFactory.generatePublic(rsaPublicKeySpec);
final RSAPrivateKey privateKey = (RSAPrivateKey) keyFactory.generatePrivate(rsaPrivateKeySpec);
return new KeyPairHolder(keyTimestamp, publicKey, privateKey);
} catch (final NoSuchAlgorithmException | InvalidKeySpecException e) {
throw new IllegalStateException("RSA problem.");
}
}
private static String createKeyTimestampNow() {
final String timestamp = DateConverter.toIsoString(LocalDateTime.now(Clock.systemUTC()));
final int index = timestamp.indexOf(".");
final String timestampWithoutNanos;
if (index > 0) {
timestampWithoutNanos = timestamp.substring(0, index);
}
else {
timestampWithoutNanos = timestamp;
}
return timestampWithoutNanos.replace(':', '_');
}
public static class KeyPairHolder {
private final String timestamp;
private final RSAPublicKey publicKey;
private final RSAPrivateKey privateKey;
public KeyPairHolder(final String timestamp, final RSAPublicKey publicKey, final RSAPrivateKey privateKey) {
super();
this.timestamp = timestamp;
this.publicKey = publicKey;
this.privateKey = privateKey;
}
public RSAPublicKey publicKey() {
return publicKey;
}
public RSAPrivateKey privateKey() {
return privateKey;
}
public String getTimestamp() {
return timestamp;
}
public BigInteger getPublicKeyMod() {
return publicKey.getModulus();
}
public BigInteger getPublicKeyExp() {
return publicKey.getPublicExponent();
}
public BigInteger getPrivateKeyMod() {
return privateKey.getModulus();
}
public BigInteger getPrivateKeyExp() {
return privateKey.getPrivateExponent();
}
}
}