Java读取RSA公私钥 密钥结构 加解密示例 非对称加解密padding

2017-02-22 22:01:00
admin
原创 3358
摘要:Java读取RSA公私钥 密钥结构 加解密示例 非对称加解密padding

一、读取RSA公私钥

1、Java使用RSA公钥格式是X.509

2、Java使用RSA私钥格式是PKCS#8

3、测试重复生成公私钥,公钥长度没有变化,私钥长度会有细微变化;


代码示例:

KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");  
keyGen.initialize(512);//RSA keys must be at least 512 bits long
KeyPair key = keyGen.generateKeyPair();
byte[] pubBytes = null;
byte[] priBytes = null;

PublicKey pubKey = key.getPublic();
pubBytes = pubKey.getEncoded();
X509EncodedKeySpec pubX509 = new X509EncodedKeySpec(pubBytes);

PrivateKey priKey = key.getPrivate();
priBytes = priKey.getEncoded();
PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(priBytes);

KeyFactory factory = KeyFactory.getInstance("RSA");
PublicKey pubkey2 = factory.generatePublic(pubX509);
PrivateKey prikey2 = factory.generatePrivate(priPKCS8);
System.out.println(pubKey.equals(pubkey2));
System.out.println(priKey.equals(prikey2));


输出:

true
true


二、RSA密钥结构

代码示例:

public static void showKey() throws Exception {
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");  
keyGen.initialize(1024);
KeyPair key = keyGen.generateKeyPair();
RSAPublicKey pubKey = (RSAPublicKey)key.getPublic();
RSAPrivateKey priKey = (RSAPrivateKey)key.getPrivate();
System.out.println(pubKey.getModulus());
System.out.println(pubKey.getPublicExponent());

System.out.println(priKey.getModulus());
System.out.println(priKey.getPrivateExponent());
}


输出:

97931010009304675619765519288
65537
97931010009304675619765519288
60796513011559424939588017727


三、RSA加解密示例

示例代码:

public static byte[] rsaEnc(PublicKey key, byte[] data) {
try {
Cipher cipher = Cipher.getInstance("RSA/ECB/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, key);
return cipher.doFinal(data);
} catch (Exception e) {
throw new RuntimeException(e);
}
}

public static byte[] rsaDec(PrivateKey key, byte[] data) {
try {
Cipher cipher = Cipher.getInstance("RSA/ECB/NoPadding");
cipher.init(Cipher.DECRYPT_MODE, key);
return cipher.doFinal(data);
} catch (Exception e) {
throw new RuntimeException(e);
}
}

public static void rsaDemo() throws Exception {
int keyLen = 1024;
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");  
keyGen.initialize(keyLen);
KeyPair key = keyGen.generateKeyPair();
PublicKey pubKey = key.getPublic();
PrivateKey priKey = key.getPrivate();

byte[] data = "feinen".getBytes();
byte[] dataByte = new byte[keyLen/8];
System.arraycopy(data, 0, dataByte, 0, data.length);
byte[] ciphertext = rsaEnc(pubKey, dataByte);
System.out.println(ciphertext.length * 8);
byte[] plaintext = rsaDec(priKey, ciphertext);
System.out.println(plaintext.length * 8);

System.out.println(Hex.encodeHex(data));
System.out.println(Hex.encodeHex(ciphertext));
System.out.println(Hex.encodeHex(plaintext));
}


输出:

1024
1024

6665696e656e

984a463e98ab4f24a4eb36352187978d4f
6665696e656e0000000000000000000000


四、非对称加解密padding

RSA_NO_PADDING:

无填充模式,加密数据长度必须等于RSA_size(rsa);


RSA_PKCS1_PADDING:

即PKCS#1 v1.5 padding,目前使用最广泛的填充模式,加密数据长度必须小于RSA_size(rsa)−11;

会填充随机数导致每次加密结果不一样;


RSA_PKCS1_OAEP_PADDING:
定义在PKCS#1 v2.0,新项目建议使用这种填充模式,加密数据长度必须小于RSA_size(rsa)−41 ;

会填充随机数导致每次加密结果不一样;

发表评论
评论通过审核之后才会显示。