`
huangjinjin520
  • 浏览: 71411 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

RSA加密解密及数字签名Java实现

阅读更多
RSA公钥加密算法是1977年由罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的。当时他们三人都在麻省理工学院工作。RSA就是他们三人姓氏开头字母拼在一起组成的。
    RSA是目前最有影响力的公钥加密算法,它能够抵抗到目前为止已知的绝大多数密码攻击,已被ISO推荐为公钥数据加密算法。
    RSA算法是一种非对称密码算法,所谓非对称,就是指该算法需要一对密钥,使用其中一个加密,则需要用另一个才能解密。
    关于RSA算法的原理,这里就不再详加介绍,网上各种资源一大堆。下面就开始介绍RSA加密解密JAVA类的具体实现。
import java.security.MessageDigest;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

public class Coder {

public static final String KEY_SHA="SHA";
public static final String KEY_MD5="MD5";

/**
* BASE64解密
* @param key
* @return
* @throws Exception
*/
public static byte[] decryptBASE64(String key) throws Exception{
return (new BASE64Decoder()).decodeBuffer(key);
}

/**
* BASE64加密
* @param key
* @return
* @throws Exception
*/
public static String encryptBASE64(byte[] key)throws Exception{
return (new BASE64Encoder()).encodeBuffer(key);
}

/**
* MD5加密
* @param data
* @return
* @throws Exception
*/
public static byte[] encryptMD5(byte[] data)throws Exception{
MessageDigest md5 = MessageDigest.getInstance(KEY_MD5);
md5.update(data);
return md5.digest();
}

/**
* SHA加密
* @param data
* @return
* @throws Exception
*/
public static byte[] encryptSHA(byte[] data)throws Exception{
MessageDigest sha = MessageDigest.getInstance(KEY_SHA);
sha.update(data);
return sha.digest();
}
}
     先提供Coder编码类,该类封装了基本的Base64、md5和SHA加密解密算法。Java对这些算法的实现提供了很好的API封装,开发人员只需调用这些API就可很简单方便的实现数据的加密与解密。
    下面提供RSA加密解密类,该类为Coder类子类,因为其中对RSA公私密钥的保存进行了一层Base64加密处理。
    RSA加密解密类静态常量
       public static final String KEY_ALGORTHM="RSA";//
public static final String SIGNATURE_ALGORITHM="MD5withRSA";

public static final String PUBLIC_KEY = "RSAPublicKey";//公钥
public static final String PRIVATE_KEY = "RSAPrivateKey";//私钥


    RSA加密解密的实现,需要有一对公私密钥,公私密钥的初始化如下:
/**
* 初始化密钥
* @return
* @throws Exception
*/
public static Map<String,Object> initKey()throws Exception{
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(KEY_ALGORTHM);
keyPairGenerator.initialize(1024);
KeyPair keyPair = keyPairGenerator.generateKeyPair();

//公钥
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
//私钥
RSAPrivateKey privateKey =  (RSAPrivateKey) keyPair.getPrivate();

Map<String,Object> keyMap = new HashMap<String, Object>(2);
keyMap.put(PUBLIC_KEY, publicKey);
keyMap.put(PRIVATE_KEY, privateKey);

return keyMap;
}
      从代码中可以看出密钥的初始化长度为1024位,密钥的长度越长,安全性就越好,但是加密解密所用的时间就会越多。而一次能加密的密文长度也与密钥的长度成正比。一次能加密的密文长度为:密钥的长度/8-11。所以1024bit长度的密钥一次可以加密的密文为1024/8-11=117bit。所以非对称加密一般都用于加密对称加密算法的密钥,而不是直接加密内容。对于小文件可以使用RSA加密,但加密过程仍可能会使用分段加密。
    从map中获取公钥、私钥
/**
* 取得公钥,并转化为String类型
* @param keyMap
* @return
* @throws Exception
*/
public static String getPublicKey(Map<String, Object> keyMap)throws Exception{
Key key = (Key) keyMap.get(PUBLIC_KEY); 
return encryptBASE64(key.getEncoded());    
}

/**
* 取得私钥,并转化为String类型
* @param keyMap
* @return
* @throws Exception
*/
public static String getPrivateKey(Map<String, Object> keyMap) throws Exception{
Key key = (Key) keyMap.get(PRIVATE_KEY); 
return encryptBASE64(key.getEncoded());    
}

    对于RSA产生的公钥、私钥,我们可以有两种方式可以对信息进行加密解密。私钥加密-公钥解密 和 公钥加密-私钥解密。

    私钥加密
/**
* 用私钥加密
* @param data 加密数据
* @param key 密钥
* @return
* @throws Exception
*/
public static byte[] encryptByPrivateKey(byte[] data,String key)throws Exception{
//解密密钥
byte[] keyBytes = decryptBASE64(key);
//取私钥
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORTHM);
Key privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);

//对数据加密
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, privateKey);

return cipher.doFinal(data);
}
    私钥解密
/**
* 用私钥解密 * @param data 加密数据
* @param key 密钥
* @return
* @throws Exception
*/
public static byte[] decryptByPrivateKey(byte[] data,String key)throws Exception{
//对私钥解密
byte[] keyBytes = decryptBASE64(key);

PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORTHM);
Key privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
//对数据解密
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, privateKey);

return cipher.doFinal(data);
}
    公钥加密
/**
* 用公钥加密
* @param data 加密数据
* @param key 密钥
* @return
* @throws Exception
*/
public static byte[] encryptByPublicKey(byte[] data,String key)throws Exception{
//对公钥解密
byte[] keyBytes = decryptBASE64(key);
//取公钥
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORTHM);
Key publicKey = keyFactory.generatePublic(x509EncodedKeySpec);

//对数据解密
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, publicKey);

return cipher.doFinal(data);
}
    私钥加密
/**
* 用公钥解密
* @param data 加密数据
* @param key 密钥
* @return
* @throws Exception
*/
public static byte[] decryptByPublicKey(byte[] data,String key)throws Exception{
//对私钥解密
byte[] keyBytes = decryptBASE64(key);
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORTHM);
Key publicKey = keyFactory.generatePublic(x509EncodedKeySpec);

//对数据解密
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, publicKey);

return cipher.doFinal(data);
}
    关于数字签名,先了解下何为数字签名。数字签名,就是只有信息的发送者才能产生的别人无法伪造的一段数字串,这段数字串同时也是对信息的发送者发送信息真实性的一个有效证明。数字签名是非对称密钥加密技术与数字摘要技术的应用。简单地说,所谓数字签名就是附加在数据单元上的一些数据,或是对数据单元所作的密码变换。这种数据或变换允许数据单元的接收者用以确认数据单元的来源和数据单元的完整性并保护数据,防止被人(例如接收者)进行伪造。
    数字签名的主要功能如下:

    保证信息传输的完整性、发送者的身份认证、防止交易中的抵赖发生。
    数字签名技术是将摘要信息用发送者的私钥加密,与原文一起传送给接收者。接收者只有用发送者的公钥才能解密被加密的摘要信息,然后用对收到的原文产生一个摘要信息,与解密的摘要信息对比。如果相同,则说明收到的信息是完整的,在传输过程中没有被修改,否则说明信息被修改过,因此数字签名能够验证信息的完整性。
    数字签名是个加密的过程,数字签名验证是个解密的过程。
     数字签名算法依靠公钥加密技术来实现的。在公钥加密技术里,每一个使用者有一对密钥:一把公钥和一把私钥。公钥可以自由发布,但私钥则秘密保存;还有一个要求就是要让通过公钥推算出私钥的做法不可能实现。
    普通的数字签名算法包括三种算法:
    1.密码生成算法;
    2.标记算法;
   3.验证算法。
    通过RSA加密解密算法,我们可以实现数字签名的功能。我们可以用私钥对信息生成数字签名,再用公钥来校验数字签名,当然也可以反过来公钥签名,私钥校验。
    私钥签名

/**
* 用私钥对信息生成数字签名
* @param data //加密数据
* @param privateKey //私钥
* @return
* @throws Exception
*/
public static String sign(byte[] data,String privateKey)throws Exception{
//解密私钥
byte[] keyBytes = decryptBASE64(privateKey);
//构造PKCS8EncodedKeySpec对象
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(keyBytes);
//指定加密算法
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORTHM);
//取私钥匙对象
PrivateKey privateKey2 = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
//用私钥对信息生成数字签名
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
signature.initSign(privateKey2);
signature.update(data);

return encryptBASE64(signature.sign());
}
    公钥校验

/**
* 校验数字签名
* @param data 加密数据
* @param publicKey 公钥
* @param sign 数字签名
* @return
* @throws Exception
*/
public static boolean verify(byte[] data,String publicKey,String sign)throws Exception{
//解密公钥
byte[] keyBytes = decryptBASE64(publicKey);
//构造X509EncodedKeySpec对象
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(keyBytes);
//指定加密算法
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORTHM);
//取公钥匙对象
PublicKey publicKey2 = keyFactory.generatePublic(x509EncodedKeySpec);

Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
signature.initVerify(publicKey2);
signature.update(data);
//验证签名是否正常
return signature.verify(decryptBASE64(sign));

}
       对于RSA如何加密文件、图片等信息,加密的信息又如何保存,怎样保存解密后的信息,以及操作过程中遇到的错误将如何处理,将在后面的文章中介绍给大家。

  
分享一份spring cloud视频
关注公众号回复 springcloud 获取



原文地址:https://my.oschina.net/jiangli0502/blog/171263
  • 大小: 39.9 KB
分享到:
评论

相关推荐

    Java实现的RSA加密解密算法示例

    RSA加密解密算法广泛应用于各种场景,例如网络支付、数据加密、数字签名等。Java中的RSA加密解密算法实现可以应用于各种Java项目,例如移动应用、Web应用等。 本文详细介绍了Java实现的RSA加密解密算法,包括密钥对...

    C# 实现与JAVA互通 加签/验签,RSA加密/解密

    * RSA加密解密:私钥解密,公钥加密。 * RSA数字签名-俗称加签验签:私钥加签,公钥验签。  * RSA加密解密:私钥解密,公钥加密。 * RSA数字签名-俗称加签验签:私钥加签,公钥验签。  * RSA加密解密:私钥...

    JAVA实现RSA加密解密

    在Java中实现RSA加密解密,可以帮助开发者保护敏感信息,例如在网络传输过程中防止数据被窃取。 首先,了解RSA的工作原理至关重要。它基于两个大素数的乘积,生成一对密钥:公钥和私钥。公钥可以公开,用于加密信息...

    C#与java平台RSA加密解密签名验签互通案例

    本案例聚焦于"C#与Java平台RSA加密解密签名验签互通"的问题,这涉及到两个主要的技术点:RSA加密算法和跨平台兼容性。下面将详细阐述这两个知识点。 首先,RSA是一种非对称加密算法,由Ron Rivest、Adi Shamir和...

    Java与.NET RSA加密解密(签名,验签)实例代码

    本实例代码着重于Java与.NET平台之间的RSA加密解密及签名验签操作,这对于跨平台的数据安全通信具有实际意义,例如与支付宝POS对接时。 1. **RSA算法基础**: RSA是一种基于大数因子分解困难性的公钥密码体制。它...

    Delphi ,Java,php等通用 RSA加密,解密,签名.

    在Delphi中,可以使用第三方库如CryptoAPI或OpenSSL来实现RSA加密。首先,需要导入相应的库,然后创建公钥和私钥对。使用公钥进行加密,私钥进行解密。对于签名,私钥用于生成签名,公钥用于验证签名。具体代码实现...

    java RSA加密 解密

    Java RSA 加密解密是一种常用的非对称加密算法,广泛应用于数据加密和数字签名等领域。但是,RSA 加密算法的速度相对较慢,一般不用于加密大数据,而是用于加密对称加密的密钥,以保证数据的安全。 相关知识点: *...

    Delphi标准RSA加密,解密,签名.与C,Java,php等通用

    RSA是一种非对称加密算法,由Ron ...通过以上介绍,我们可以看出Delphi中的RSA加密、解密和签名实现并不复杂,但涉及到的关键技术与理论基础深厚。开发者在实际应用中应确保遵循最佳实践,以保证系统的安全性和可靠性。

    Android使用RSA加密解密功能的实现Demo

    本教程将详细介绍如何在Android项目中实现RSA加密解密功能,并通过一个Demo来说明其具体步骤。 首先,我们需要了解RSA加密的基本原理。RSA是由Ron Rivest、Adi Shamir和Leonard Adleman三位科学家于1977年提出的,...

    Java实现RSA加密解密签名校验

    Java实现RSA加密解密签名校验是信息安全领域中常见的任务,尤其在数据传输和网络通信中,RSA算法因其非对称性的特点,被广泛应用于数据的加密、解密以及数字签名。下面将详细介绍RSA算法的基本原理,以及如何使用...

    asp.net RSA 私钥加密公钥解密 能解 php Java 实现RSA加密互通

    本文将深入探讨如何在ASP.NET环境中实现RSA加密,并且与PHP和Java进行互通,以及涉及的PKCS#8格式的密钥文件和BouncyCastle.Crypto.dll库的使用。 首先,RSA是一种基于大素数因子分解困难性的公钥加密算法,由Ron ...

    Java实现RSA加密解密,数字证书生成与验证

    Java实现RSA加密解密,数字证书生成与验证,模拟两个端通信,AB双方通信,客户端A把需要传输的文件MD5值用自己的私钥生成数字签名,连同明文用服务端B的公钥加密后传送给服务端B,服务端B用私钥解密验证数字签名,并计算...

    RSA 加密 解密 C# Java 转化.zip

    可以实现C# Rsa加密(私钥加密、公钥解密、密钥格式转换、支持超大长度分段加密).net 转 java,java 转 .net 比如有一个开放平台:和目平台 亲测可用。他们就是只提供java的密钥,我已成功调用!如果有疑问需要...

    Java RSA 加密解密

    Java RSA 加密解密是一...总的来说,Java RSA加密解密是保证数据安全传输的重要手段,其核心概念和操作流程在上述代码中得到了体现。实际开发时,还需要注意处理异常,以及根据具体需求选择合适的加密模式和填充方式。

    AES+RSA加密解密(js和java互通)

    在这个项目中,我们关注的是"AES+RSA加密解密",这是两种广泛使用的加密算法,适用于JavaScript和Java环境中的前后端数据交换。下面将详细介绍这两个加密算法以及如何实现它们的互通。 **AES(Advanced Encryption ...

    Java实现文件的RSA和DES加密

    Java 实现文件的 RSA 和 DES 加密 在现代密码技术中,根据密钥类型的不同,可以将其分为两类:对称加密算法(秘密钥匙加密)和非对称加密算法(公开密钥加密)。对称加密算法用来对敏感数据等信息进行加密,常用的...

    java RSA加密解密

    在Java中,我们可以通过以下步骤实现RSA加密解密: 1. **生成密钥对**: - 使用`KeyPairGenerator`类的`getInstance("RSA")`方法获取RSA密钥对生成器。 - 调用`initialize`方法设置密钥长度(通常为2048位或更长...

    rsa aes 加密解密 以及rsa 签名以及验证

    这些类可能包括用于AES和RSA加密解密的方法,以及RSA签名和验证的方法。这些工具类通常会提供便利的API,使得开发人员能够轻松地在应用程序中集成这些安全功能。 总之,理解AES和RSA加密算法以及它们的使用场景,是...

    RSA加密解密,签名验证代码

    在Android和Java平台实现RSA加密解密,主要涉及以下几个步骤: 1. **密钥生成**:首先,我们需要生成RSA密钥对。这通常通过`KeyPairGenerator`类来实现,指定算法为"RSA",并设置密钥长度,比如2048位。生成的密钥...

    RSA2--》加签+加密+解密+验签

    RSA算法是一种非对称加密算法,它在信息安全领域有着广泛的应用,特别是在数字签名、数据加密和安全通信中。本文将详细讲解RSA算法的加签、加密、解密以及验签的过程,结合Java语言来实现这一系列操作,并涉及到证书...

Global site tag (gtag.js) - Google Analytics