基于RSA的加密、解密、数字签名

 

RSA算法出现于1978年,算法的名字以发明者的名字命名:Ron Rivest, AdiShamir 和Leonard Adleman,是第一个既能用于数据加密也能用于数字签名的算法。这种加密算法的特点主要是密钥的变化,与DES只有一个密钥相比较,RSA同时有两把钥匙,公钥与私钥。同时支持数字签名。数字签名的意义在于,对传输过来的数据进行校验,确保数据在传输工程中不被修改。

 

RSA加密、解密、数字签名流程:

1、A构建密钥对:公钥、私钥,将公钥公布给B,将私钥保留。

2、A使用私钥加密数据,然后用私钥对加密后的数据签名,发送给B签名以及加密后的数据;B使用公钥、签名来验证待解密数据是否有效,如果有效使用公钥对数据解密。

3、B使用公钥加密数据,向A发送经过加密后的数据;A获得加密数据,通过私钥解密。

 

应用:由于RSA是一种既可用于数据的加密和解密,也可以进行数字签名的算法,所以也可以用于软件的许可文件的注册或者sso的登录信息加密。

 

example:

 

初始化密钥:

 

// KeyPair生成器

KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");

keyPairGen.initialize(1024);

KeyPair keyPair = keyPairGen .genKeyPair();


PublicKey publicKey = keyPair.getPublic(); // 公钥

PrivateKey privateKey = keyPair.getPrivate(); // 私钥

 

// 将公钥写成文件,便于存放和迁移

KeyFactory keyFactory = KeyFactory.getInstance("RSA");

RSAPublicKeySpec rsaPublicSpec = (RSAPublicKeySpec)keyFactory .getKeySpec(publicKey, RSAPublicKeySpec.class);

PublicKeySpec licenseKey = new PublicKeySpec(rsaPublicSpec);

 

String storePath = "d:/";

File licensePath = new File(storePath);
File keyPath = new File(licensePath.getAbsolutePath().substring(0,
             licensePath.getAbsolutePath().lastIndexOf(File.separator)) + File.separator + "public.key");
FileOutputStream fKey = new FileOutputStream(keyPath);
ObjectOutputStream oos = new ObjectOutputStream(fKey);
oos.writeObject(licenseKey);
oos.close();

 

 // 使用私钥对文件进行数字签名

 String srcstr = "<user><username></username><password></password></user>";

 byte[] input = srcstr.getBytes();

 Signature s = Signature.getInstance("MD5withRSA");
 s.initSign(privateKey);
 s.update(input);
 byte[] result = s.sign(); // 生成的签名结果

 

// 用公钥进行数字签名校验

byte[] data = srcstr.getBytes(); // 待校验文件

byte[] signature = result; // 数字签名证书文件流

KeyFactory keyfactory = KeyFactory.getInstance("RSA");

FileInputStream fis = new FileInputStream(new File(publicKeySpecPath));

ObjectInputStream ois = new ObjectInputStream(fis);

PublicKeySpec publicKeySpec = (PublicKeySpec) ois.readObject();

PublicKey publicKey = keyfactory.generatePublic(publicKeySpec.genRSAPublicKeySpec());

Signature s = Signature.getInstance("MD5withRSA");
s.initVerify(publicKey);
s.update(data);
boolean isRight = s.verify(signature);

 

// 用公钥加密

KeyFactory keyFactory = KeyFactory.getInstance("RSA"); 

byte[] data = srcstr.getBytes();

 

// publicKeySpecPath为生成公钥的文件

FileInputStream fis = new FileInputStream(new File(publicKeySpecPath));

ObjectInputStream ois = new ObjectInputStream(fis);

PublicKeySpec publicKeySpec = (PublicKeySpec) ois.readObject();

PublicKey publicKey = keyfactory.generatePublic(publicKeySpec.genRSAPublicKeySpec()); // 取得公钥

Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());

cipher.init(Cipher.ENCRYPT_MODE, publicKey);   
byte[] encryptdata = cipher.doFinal(data);   

 

// 用私钥解密

KeyFactory keyFactory = KeyFactory.getInstance("RSA");   

byte[] data = srcstr.getBytes();

 

// publicKeySpecPath为生成私钥的文件

byte[] keyBytes = key.getEncoded();

PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);  

 

// 对数据解密   

Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());   

cipher.init(Cipher.DECRYPT_MODE, privateKey);   
byte[] decryptdata = cipher.doFinal(data);   

 

// 用私钥加密

KeyFactory keyFactory = KeyFactory.getInstance("RSA");   

byte[] data = srcstr.getBytes();

 

// publicKeySpecPath为生成私钥的文件

byte[] keyBytes = privateKey.getEncoded();

PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);  

 

// 对数据解密   

Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());   

cipher.init(Cipher.ENCRYPT_MODE, privateKey);   
byte[] decryptdata = cipher.doFinal(data);

 

// 用公钥解密

KeyFactory keyFactory = KeyFactory.getInstance("RSA"); 

byte[] data = srcstr.getBytes();

 

// publicKeySpecPath为生成公钥的文件

FileInputStream fis = new FileInputStream(new File(publicKeySpecPath));

ObjectInputStream ois = new ObjectInputStream(fis);

PublicKeySpec publicKeySpec = (PublicKeySpec) ois.readObject();

PublicKey publicKey = keyfactory.generatePublic(publicKeySpec.genRSAPublicKeySpec()); // 取得公钥

// ===================也可以直接通过PublicKey取得==================

byte[] keyBytes = publicKey.getEncoded();

PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
Key publicKey = keyFactory.generatePublic(pkcs8KeySpec);

// ================================================================

Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());

cipher.init(Cipher.DECRYPT_MODE, publicKey);   
byte[] encryptdata = cipher.doFinal(data);    

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值