环境准备:下载安装Win64OpenSSL-1_1_0i.exe和jdk_1.8
一、生成.ssh文件(用于远程登陆)
生成 id_rsa 和 id_rsa.pub 文件
ssh-keygen [-q] [-b bits] [-C comment] [-f output_keyfile] [-m format] [-t dsa | ecdsa | ecdsa-sk | ed25519 | ed25519-sk | rsa] [-N new_passphrase] [-O option] [-w provider]
可以简单生成一个2048位的密钥对
ssh-keygen -t rsa -b 2048 -m PEM -C "message"
将公钥发送到目标主机
ssh-copy-id [ip]
如果修改了22端口为14000,那么可以使用命令
ssh-copy-id -i id_rsa.pub "-p14000" [email protected]
执行成功之后,我们在目标机器上查看/root/.ssh目录已经生成,并且多了一个名为authorized_keys的文件,里面保存的正是原机器上ssh-keygen生成的id_rsa.pub的内容。
- id_rsa:私钥
- id_rsa.pub:公钥
- authorized_keys:存储了可以远程登陆本机的节点的公钥
- known_hosts:连接到本机的节点的信息,包括远程机器ip、远程机器公钥。
ssh 远程密钥登陆命令是:
ssh -i /path/to/private/key username@remote_host
二、openssl的证书指令
2.1 基本命令
生成私钥
openssl genrsa -aes256 -out rsaprivatekey.pem 2048
- 生成rsa私钥,aes256算法,2048位强度,密钥文件为server.key。
生成公钥
openssl rsa -in rsaprivatekey.pem -out rsapublickey.pem -pubout
将私钥进行pkcs8编码给java用
openssl pkcs8 -topk8 -inform PEM -in rsaprivatekey.pem -outform PEM -out rsaprivatekey_pkcs8.pem -nocrypt
2.2 生成证书
2.2.1 创建自签名证书
-
生成私钥
openssl genrsa -aes256 -out server.key 2048
-
生成CSR(证书签名请求)
Csr是证书请求文件,用于申请证书。openssl req -new -key server.key -out server.csr
如果要支持https,Common Name应该与域名保持一致,否则会引起浏览器警告。
-
删除私钥中的密码
在第1步创建私钥的过程中,由于必须要指定一个密码。而这个密码会带来一个副作用,那就是在每次启动Web服务器时,都会要求输入密码,这显然非常不方便。
要删除私钥中的密码,操作如下:openssl rsa -in server.key -out server.key
-
生成自签名证书CRT
crt是CA认证后的证书。用私钥server.key给csr签名后得到crt证书。openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
2.2.2 私有CA签名证书(推荐)
-
创建root CA私钥
openssl req -newkey rsa:4096 -nodes -sha256 -keyout ca.key -x509 -days 365 -out ca.crt
CN输入ca.rancher.com
-
为服务端生成证书签名请求文件
openssl req -newkey rsa:4096 -nodes -sha256 -keyout demo.rancher.com.key -out demo.rancher.com.csr
CN输入demo.rancher.com;
注意:Commone Name一定要是你要授予证书的FQDN域名或主机名,并且不能与生成root CA设置的Commone Name相同
-
用第一步创建的CA证书给第二步生成的签名请求进行签名
openssl x509 -req -days 365 -in demo.rancher.com.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out demo.rancher.com.crt
4.如果您使用IP,例如192.168.1.101来连接,则可以改为运行以下命令:
echo 'subjectAltName = IP:192.168.1.101' > extfile.cnf
openssl x509 -req -days 365 -in demo.rancher.com.csr -CA ca.crt -CAkey ca.key -CAcreateserial -extfile extfile.cnf -out demo.rancher.com.crt
2.3 验证证书
注意: 因为使用的是自签名证书,浏览器会提示证书的颁发机构是未知的。
把生成的ca证书和去除密码的私钥文件部署到web服务器后,执行以下命令验证:
openssl s_client -connect demo.rancher.com:443 -servername demo.rancher.com -CAfile server-ca.crt
三、java库的证书指令指令
3.1 基础命令
3.1.1 增
使用JDK自带工具keytool生成keystore和自签名证书
keytool -genkeypair -keystore ./keystore -storepass hxrhxr123 -alias hxr -keypass hxrhxr123 -keyalg RSA -keysize 1024 -validity 365
- -keystore:秘钥库文件名,保存了生成的证书
- -storepass:秘钥库的访问密码
- -alias:秘钥别名,默认 "mykey"
- -keypass:秘钥的访问密码
- -keyalg:使用的hash算法,默认"DSA"
- -keysize:密钥长度,默认1024
- -validity:有效期,默认365天
创建新的密钥
keytool -genkeypair -alias jetty2 -keypass bigdata123 -keyalg RSA -keysize 1024 -validity 365 -dname "CN=www.chenjie.asia,OU=,L=,ST=,C=" -keystore ./keystore -storepass hxrhxr123
- -dname:指定证书拥有者信息 "CN=名字与姓氏,OU=组织单位名称,O=组织名称,L=城市或区域名称,ST=州或省份名称,C=单位的两字母国家代码"
导入证书文件到密钥库中
keytool -import -alias jetty3 -file ./test.cer -keystore ./keystore -storepass hxrhxr123
导出密钥库中的证书密钥
keytool -export [-rfc] -file ./jwt.crt -keystore ./keystore -storepass hxrhxr123 -alias jetty -keypass hxrhxr123
查看导出的crt证书信息
keytool -printcert -file "test.crt"
3.1.2 查
查看密钥库中所有密钥
keytool -list [-v] -keystore jwtstore -storepass hxrhxr123
- -v:打印所有密钥的详细信息
查看别名是hxr 的证书信息
keytool -list [-v] [-rfc] -alias hxr -keystore jwtstore -storepass hxrhxr123
指定了 -v 选项,将以可读格式打印证书,如果指定了 -rfc 选项,将以可打印的编码格式输出证书。
openssl查看公钥
keytool -list -rfc --keystore uaacenter.jks | openssl x509 -inform pem -pubkey
3.1.3 改
修改密钥库密码
keytool -keypasswd -new test1 -keystore ./keystore -storepass hxrhxr123
修改秘钥库中秘钥的密码
keytool -keypasswd -new testtest1 -keystore jwtstore -storepass hxrhxr123 -alias hxr -keypass hxrhxr123
修改密钥库中密钥的信息
keytool -selfcert -dname "cn=chenjie.asia,ou=,o=,c=" -keystore ./keystore -storepass hxrhxr123 -alias jetty -keypass hxrhxr123
3.1.4 删
删除别名是hxr的证书信息
keytool -delete -alias hxr -keystore jwtstore -storepass hxrhxr123
3.1.5 jar包签名
对InetAddress-1.0-SNAPSHOT.jar包进行签名
jarsigner -verbose -signedjar ./InetAddress-1.0-SNAPSHOT.jar.signed -keystore ./keystore -storepass hxrhxr123 -keypass bigdata123 ./InetAddress-1.0-SNAPSHOT.jar jetty
- -verbose 打印详细信息
- -signedjar 签名后文件存放的路径
对签名后的文件进行验证
jarsigner -verbose -verify InetAddress-1.0-SNAPSHOT.jar.signed
如果jar包中的文件被篡改,则验证不通过。
如我们修改了jar包中的pom.xml文件的内容,再进行验证,报错如下
D:\>jarsigner -verify InetAddress-1.0-SNAPSHOT.jar
jarsigner: java.lang.SecurityException: SHA-256 digest error for META-INF/maven/org.example/InetAddress/pom.xml
3.2 使自签名证书受信任
3.2.1 将证书导出
keytool -export -rfc -file ./hxr.cer -alias jetty -keystore ./keystore -storepass hxrhxr123
3.2.2 使客户端信任服务器
- 使chrome浏览器信任
进入浏览器的【设置】-【隐私设置和安全性】-【安全】-【管理证书】中,添加证书到 "受信任的根证书颁发机构"即可。
也可以直接双击证书安装到电脑中。
重启浏览器,再次访问网页发现证书已被信任。
可是还是不被信任 NET::ERR_CERT_COMMON_NAME_INVALID???奇怪!!!
- 使centos7.x服务器信任
将导出的证书内容追加到/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem文件中
cat /etc/security/keytab/cos-bigdata-test-hadoop-01.cer >> /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem
再次请求就不会报证书不受信任。
- 使jdk信任证书
将证书添加到jdk的信任库中,jdk的信任库文件是cacerts。
这种情况的使用场景就是,有框架是java编写的程序,在框架中请求一个自签名证书配置的https服务,如果不配置证书信任就会导致请求失败。如hadoop框架中,如果配置了Https-only且证书是自签名证书,那么默认每分钟Secondarynamenode会发起fetchImage的https请求,如果不配置自签名证书可信任,就会导致请求失败,Secondarynamenode功能失效。keytool -import -v -trustcacerts -alias cos-bigdata-test-hadoop-01 -file /etc/security/keytab/cos-bigdata-test-hadoop-01.crt -keystore $JAVA_HOME/jre/lib/security/cacerts -storepass changeit
keytool和openssl的区别:keytool没办法签发证书,而openssl能够进行签发和证书链的管理。
因此,keytool 签发的所谓证书只是一种自签名证书。所谓自签名就是指证书只能保证自己是完整的,没有经过非法修改的。但是无法保证这个证书是属于谁的。
自签名证书有个很麻烦地方:对于每一个要链接的服务器,都要保存一个证书的验证副本。而且一旦服务器更换证书,所有客户端就需要重新部署这些副本。
也就是说,你可以用自签名证书让承认你的人承认你。但如果你做了一丁点变化,你需要让所有之前承认你的人再次承认你。
对于比较大型的应用来说,这一点是不可接受的。所以就需要证书链进行 双向认证。而 证书链,keytool自己就没办法做了,需要用到 openssl.
四、通过代码获取秘钥库的公私钥并对jwt进行签名和验签
public class KeyPairTest {
@Test
public void testCreateToken(){
String location = "uaacenter.jks";
String storepass = "uaacenter";
String keypass = "uaacenter";
String alias = "uaacenter";
//加载证书
ClassPathResource resource = new ClassPathResource(location);
//读取证书
KeyStoreKeyFactory keyStoreKeyFactory = new KeyStoreKeyFactory(resource,storepass.toCharArray());
//获取证书中的一对秘钥
KeyPair keyPair = keyStoreKeyFactory.getKeyPair(alias,keypass.toCharArray());
//获取私钥
RSAPrivateKey aPrivate = (RSAPrivateKey)keyPair.getPrivate();
System.out.println(Base64.encode(aPrivate.getEncoded()));
//创建令牌,需要私钥加盐[RSA算法]
Jwt jwt = JwtHelper.encode("abcdefg", new RsaSigner(aPrivate));
//将令牌用base64编码得到token
String token = jwt.getEncoded();
System.out.println(token);
}
@Test
public void testParseToken(){
//TODO 获取公钥方式一:通过代码从证书库获得公钥
String location = "uaacenter.jks";
String storepass = "uaacenter";
String keypass = "uaacenter";
String alias = "uaacenter";
//加载证书
ClassPathResource resource = new ClassPathResource(location);
//读取证书
KeyStoreKeyFactory keyStoreKeyFactory = new KeyStoreKeyFactory(resource,storepass.toCharArray());
//获取证书中的一对秘钥
KeyPair keyPair = keyStoreKeyFactory.getKeyPair(alias,keypass.toCharArray());
//获取公钥
RSAPublicKey aPublic = (RSAPublicKey)keyPair.getPublic();
System.out.println(Base64.encode(aPublic.getEncoded()));
//TODO 获取公钥方式二:通过openssl指令获取公钥
//需要带上begin和end信息,并且去掉换行符
// String aPublic= "-----BEGIN PUBLIC KEY-----MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAo668mNH7H86PzBCHsMsm7/Hxg4tK6YVWBWt74faDVrew6AzHfXz1S74ZoG5ftWt7hsQh2cFzpbnuMIYrhZatTEhnYNJA6T47meSb476WSc70/59w+21EIeQTbWUNhBZeA9r/M2u5ItBBJksyWSmMM6c2YRCeF7HC/KHFFGhWc46y9x6r3iqOrwnCAsrSjz9cIEvlCVgewLMxU5x9H/INZoqH3ZR8jUv/fIxFfju11izUrpxTb16SYC/t46Lb5l0Kynmrv4OOolGk0yJgeH3vgDnS/3OhlD08vGujnI6os7acCcXwEq3SDHvtOfd/Q/CBbUcDSQuk9ecyvtgFVRvOEwIDAQAB-----END PUBLIC KEY-----";
//解析之前得到的token
String token = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.YWJjZGVmZw.n1xeWFHjmh634MBzmC5aY9Q0Jo_EKRPPfjNf9eT6dguv3ivBHkBrFCVrVDMsM-f4Gy7ObrSCt-aR18tWySfmHgv9zp30YeXYbCg2sV_-pCPLJVE8wYuFYuuqnXINYNudAhp2rfhPApjh-jJxjVIdUB9NyMlWamAF7y-y3r2ox_32y0vqGQtNc6M6d9JR_MifVQWink8rGvhs-FVJlwDbhMt88kxsB9dOWhTspeQk9exfJIV_hDFhYiXLdQapG4t6FscEDeZjCRsuTfadj5KaJ3QwiWa711pZF50MBozCtE2NLSR_2UHtt_rmCMQcqDI3FphOHXN3GjadJn_gnfjpoQ";
//解码后获得jwt并通过公钥验证是否有效
Jwt jwt = JwtHelper.decodeAndVerify(token, new RsaVerifier(aPublic));
String claims = jwt.getClaims();
System.out.println(claims);
}
}
打印的privateKey为
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCjrryY0fsfzo/MEIewyybv8fGDi0rphVYFa3vh9oNWt7DoDMd9fPVLvhmgbl+1a3uGxCHZwXOlue4whiuFlq1MSGdg0kDpPjuZ5JvjvpZJzvT/n3D7bUQh5BNtZQ2EFl4D2v8za7ki0EEmSzJZKYwzpzZhEJ4XscL8ocUUaFZzjrL3HqveKo6vCcICytKPP1wgS+UJWB7AszFTnH0f8g1miofdlHyNS/98jEV+O7XWLNSunFNvXpJgL+3jotvmXQrKeau/g46iUaTTImB4fe+AOdL/c6GUPTy8a6OcjqiztpwJxfASrdIMe+05939D8IFtRwNJC6T15zK+2AVVG84TAgMBAAECggEAN/2DwfrCHkU4ZyOYZt93OEjYxpiVTYAwxrXXsJn0n2tCdn44lzJxbjFe7sQStSpJHPZmZeiIuL37PloG9TFvolJ6GmKRlbeWB7RtpuAA5MqIgBB4Q2lDDxzHkHoqv24vRr5Y4awNrlzyjDjYxisyLFEchuN6ULyb6HMlyS9Ps0Mm2KyqmTErgMdedDveWQXl/76xlKEWRDvx8xXmH/ThrOrWhFT9TXGAshL1/ifyW+eeB/xEI2WhrqYRD/nLCl4wMQ2ZiJ0bdDDcDhhyzX6GGjJ0T9scQVDh1TEqdjRwQwP22xXPPwUPoeVQw23/7eaKpCDzlJPxn2+ZdMqxRjGPoQKBgQDSNteMuvLccJaOCYaJYMUc5pTknEzkxCYI1u8/AwoGgDqA5WtJmBHOOqVYfvgH9tzLD7K4dkNWTrvXOR3uh2IQgkqt9kjBv5V0JUWBjQMkY9Z0Boefh/wZCpKdIbNmymHWgagT096/yD4rpryQ8kQo3Bk6/XXALxJkBsVMhfVzyQKBgQDHVWAAWj0llJaFQvDlEab0IrVRvWISe7FJejBkWMFddgInRd039GVbK+OukOKbw0orMsR30/kfvrBFpR6ZDGGb2ivmwxoAyI7rvaN9TrjOKb4UsnKv5FG66NUIUG8/XBfuN+wLjs9E+wg26Y1XMiZ7TBidOgcmICPL83mh+60I+wKBgQDRZKGHZD1AScIeT+y8cTFHXYPYyLxrb9s3GOoNyTg2S4p7FIuvLhQmahKDuU3VmRhMCSIMTnk6woinlRR0olSTf0VmTZohrHXx0KKQrmb/25cl0c9MoMcEJpzuekBa1qNoaZSD05rhTFRpZNgWRcyRKtTTBuBBBGJ8UqY7WICryQKBgFXq3q5INwLzwM0/xUV3Dlc8fpr03kjJN+lL2X/nIbF/I/55hpiPpwBdMo4TtRkeW+GyyCw+GastLh1WxpGBXLEooLOedJ7R04iY/NcOD2oNY/jX0ccuymud3/TtdoYA0+/B+uQgcgZxjWDd2iYzX5LVgeaDFIHCaKuIDm1bZYHxAoGBAI1tVE6ZqgIXuRMRCTRXxYgfASMuVqGOJ1IokYrC7aCq1G2VvFz8SLxYKIUUNOOaAj7aazZ6Nu6m97aECOdkQO/ATt3ha4r/GrieEUK801BbgWvTvb668WKLRgJoo9cLbDS5ZxRN1o11FNuivWzah0ih+C+3iALwO6d/HMYMKEu+
打印的publicKey如下,通过java代码获得的publicKey和openssl获得的publicKey是一致的。需要注意的是直接使用公钥字符串需要带上begin和end前后缀。
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAo668mNH7H86PzBCHsMsm7/Hxg4tK6YVWBWt74faDVrew6AzHfXz1S74ZoG5ftWt7hsQh2cFzpbnuMIYrhZatTEhnYNJA6T47meSb476WSc70/59w+21EIeQTbWUNhBZeA9r/M2u5ItBBJksyWSmMM6c2YRCeF7HC/KHFFGhWc46y9x6r3iqOrwnCAsrSjz9cIEvlCVgewLMxU5x9H/INZoqH3ZR8jUv/fIxFfju11izUrpxTb16SYC/t46Lb5l0Kynmrv4OOolGk0yJgeH3vgDnS/3OhlD08vGujnI6os7acCcXwEq3SDHvtOfd/Q/CBbUcDSQuk9ecyvtgFVRvOEwIDAQAB
public class ExportCert {
//导出证书 base64格式
public static void exportCert(KeyStore keyStore, String alias, String exportFile) throws Exception {
Certificate certificate = keyStore.getCertificate(alias);
BASE64Encoder encoder = new BASE64Encoder();
String encoded = encoder.encode(certificate.getEncoded());
FileWriter fw = new FileWriter(exportFile);
fw.write("------Begin Certificate----- \r\n ");//非必须
fw.write(encoded);
fw.write("\r\n-----End Certificate-----");//非必须
fw.close();
}
//得到KeyPair
public static KeyPair getKeyPair(KeyStore keyStore, String alias, char[] password){
try{
Key key = keyStore.getKey(alias, password);
if (key instanceof PrivateKey){
Certificate certificate = keyStore.getCertificate(alias);
PublicKey publicKey = certificate.getPublicKey();
return new KeyPair(publicKey, (PrivateKey) key);
}
}catch (UnrecoverableKeyException | NoSuchAlgorithmException | KeyStoreException e){
e.printStackTrace();
}
return null;
}
//导出私钥
public static void exportPrivateKey(PrivateKey privateKey, String exportFile) throws Exception {
BASE64Encoder encoder = new BASE64Encoder();
String encoded = encoder.encode(privateKey.getEncoded());
FileWriter fileWriter = new FileWriter(exportFile);
fileWriter.write("-----Begin Private Key-----\r\n");//非必须
fileWriter.write(encoded);
fileWriter.write("\r\n-----End Private Key-----");//非必须
fileWriter.close();
}
//导出公钥
public static void exportPublicKey(PublicKey publicKey, String exportFile) throws Exception {
BASE64Encoder encoder = new BASE64Encoder();
String encoded = encoder.encode(publicKey.getEncoded());
FileWriter fileWriter = new FileWriter(exportFile);
fileWriter.write("-----Begin Public Key-----\r\n");//非必须
fileWriter.write(encoded);
fileWriter.write("\r\n-----End Public Key-----");//非必须
fileWriter.close();
}
public static void main(String[] args) throws Exception{
String keyStoreType = "jks";
String keystoreFile = "D:\\project\\workspace\\HelloWorld\\out\\production\\HelloWorld\\kunpu\\ijvmkeys";
String password = "ijvm2ed"; //keystore的解析密码
String friendPassword = "friend4life";//条目的解析密码
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(new FileInputStream(keystoreFile), password.toCharArray());
String alias = "friend";//条目别名
String exportCertFile = "D:\\project\\workspace\\HelloWorld\\out\\production\\HelloWorld\\kunpu\\cert.txt";
String exportPrivateFile = "D:\\project\\workspace\\HelloWorld\\out\\production\\HelloWorld\\kunpu\\privateKey.txt";
String exportPublicFile = "D:\\project\\workspace\\HelloWorld\\out\\production\\HelloWorld\\kunpu\\publicKey.txt";
ExportCert.exportCert(keyStore, alias, exportCertFile);
KeyPair keyPair = ExportCert.getKeyPair(keyStore, alias, friendPassword.toCharArray()); //注意这里的密码是你的别名对应的密码,不指定的话就是你的keystore的解析密码
ExportCert.exportPrivateKey(keyPair.getPrivate(), exportPrivateFile);
ExportCert.exportPublicKey(keyPair.getPublic(), exportPublicFile);
System.out.println("OK");
}
}
将公钥字符串转化为PublicKey对象等方法
/**
* RSA加解密工具类
*/
public class RSAUtils {
//公钥加密
public static String encrypt(String content, PublicKey publicKey) {
try{
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");//java默认"RSA"="RSA/ECB/PKCS1Padding"
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] output = cipher.doFinal(content.getBytes());
BASE64Encoder encoder = new BASE64Encoder();
return encoder.encode(output);
}catch (Exception e){
e.printStackTrace();
}
return null;
}
//公钥加密
public static byte[] encrypt(byte[] content, PublicKey publicKey) {
try{
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");//java默认"RSA"="RSA/ECB/PKCS1Padding"
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
return cipher.doFinal(content);
}catch (Exception e){
e.printStackTrace();
}
return null;
}
//私钥解密
public static byte[] decrypt(byte[] content, PrivateKey privateKey) {
try {
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
return cipher.doFinal(content);
} catch (Exception e){
e.printStackTrace();
return null;
}
}
//私钥解密
public static String decrypt(String content, PrivateKey privateKey) {
try {
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte [] b = cipher.doFinal(content.getBytes());
BASE64Encoder encoder = new BASE64Encoder();
return encoder.encode(b);
} catch (Exception e){
e.printStackTrace();
return null;
}
}
/**
* String转公钥PublicKey
* @param key
* @return
* @throws Exception
*/
public static PublicKey getPublicKey(String key) throws Exception {
byte[] keyBytes;
keyBytes = (new BASE64Decoder()).decodeBuffer(key);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKey = keyFactory.generatePublic(keySpec);
return publicKey;
}
/**
* String转私钥PrivateKey
* @param key
* @return
* @throws Exception
*/
public static PrivateKey getPrivateKey(String key) throws Exception {
byte[] keyBytes;
keyBytes = (new BASE64Decoder()).decodeBuffer(key);
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
return privateKey;
}
}
Hadoop Administration