提示:
1、公钥加密只能用私钥解密。
2、私钥加密只能用公钥解密。
3、文章中的密文是指加密后的内容类似:MIGfMA0GC=
4、代码中使用Base64是为了把二进制数组转换为字符串。加密解密内容是二进制,不限于字符串。
本文说明一下非对称加密如何实现安全通讯:
A和B两个人进行安全通讯需要:A的公钥和私钥、B的公钥和私钥。
1、A和B保存好自己的私钥不要泄漏。A公开自己的公钥,B保存A的公钥;B公开自己的公钥,A保存B的公钥。
2、A发消息到B。格式如下:
from:A(说明:A名字没有加密,所有人都能看到) to:B(说明:B名字没有加密,所有人都能看到) content:X我喜欢你,你知道吗?X(说明:[X我喜欢你,你知道吗?X]是用B的公钥加密后的密文, B的私钥才能打开) sign:EG6V/RGbxYFoX1Uz4r6MgUeqh2hAb9Duj8JlB8Y5iSRxMTO1PpAH.. (说明:用B的名字和加密后的内容,用A私钥签章得到的数字印章)
3、很多人都收到了这条消息,其中包括一些想要监控你通信内容的坏人。所有人都看到A向B发消息了,有A公钥的人能验证接收者是不是自己和加密内容没有被修改过,而加密内容却只有拥有B私钥的人才能打开!
4、B向A发消息也是类似。就这样,在不安全的链路上进行安全的通讯就完成了!
附上java实现的RSA的小例子:
MainTest:
package rsa; import java.util.HashMap; import java.util.Map; public class MainTest { /** * @param args * @throws Exception */ public static void main(String[] args) { KeyGenerater kgA = new KeyGenerater(); kgA.generater(); KeyGenerater kgB = new KeyGenerater(); kgB.generater(); System.out.println("pubKeyA = " + new String(kgA.getPubKey())); System.out.println("priKeyA = " + new String(kgA.getPriKey())); System.out.println("PubKeyB = " + new String(kgB.getPubKey())); System.out.println("PriKeyB = " + new String(kgB.getPriKey())); String text = "我喜欢你,你知道吗?"+((char) 134) + ""; byte[] content=text.getBytes(); print("content :",content); byte[] contentByteEntrpted=RASUtil.encryptByPubKey( content,kgB.getPubKey()/*B的公钥*/);//A加密内容,content的内容 print("contentByteEntrpted Bytes:",contentByteEntrpted); String beSigned=new StringBuilder()//被签章的内容:包括接收者和加密后的内容,保证这些内容,用A的私钥加密后没有人可以修改签章内容。 .append(new String("B"))//确保接收者不被修改 .append(new String(contentByteEntrpted))//确保加密内容不被修改 .toString(); System.out.println("beSigned ="+beSigned); byte[] signByte=RASUtil.sign(kgA.getPriKey()/*A的私钥*/, beSigned);//A签名,sign的内容 System.out.println("signByte:"+new String(signByte)); //组装成可以进行传输的数据对象,Base64是为了字符串化二进制,方便传输(二进制里的一些特殊控制字符不适合进行传输) Map<String,String> map=new HashMap<String, String>(); map.put("from", "A"); map.put("to", "B"); map.put("content", new String(contentByteEntrpted)); map.put("sign", new String(signByte)); String beSigned_B=new StringBuilder()//B要验章。 .append(new String("B")) .append(map.get("content")) .toString(); //B验章 System.out.println("B验证签名:"+RASUtil.verify(kgA.getPubKey()/*A的公钥*/, beSigned_B, map.get("sign").getBytes()));//B验证签名,如果为true,说明内容没有被修改,且接收者必定是自己。 print("contentByteEntrpted.getBytes:",map.get("content").getBytes()); //B如果发现接收者是自己,用私钥解开内容 byte[] content2=RASUtil.decryptByPriKey(map.get("content").getBytes(), kgB.getPriKey()/*B的私钥*/); content2=Base64.decode(content2); print("content2:",content2); System.out.println("加密解密无误:"+equals(content,content2));//只要保证,byte数组的每一个都是相等的即证明加密解密无误 //System.out.println(new String(content2).equals(new String(content)));//true //System.out.println(new String(content2).equals(text));//false,byte数组和字符串转换时,最后那个特殊char转换后发生变化导致。 } private static boolean equals(byte[] b, byte[] m2) { try{ for (int i = 0; i < m2.length; i++) { if(b[i]!=m2[i]){ return false; } } return true; }catch (Exception e) { return false; } } private static void print(String s,byte[] m) { System.out.print(s); for (int i = 0; i < m.length; i++) { System.out.print(Byte.valueOf(m[i]).intValue()); System.out.print(","); } System.out.println(); } }
KeyGenerater:
package rsa; import java.security.KeyPair; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; public class KeyGenerater { private byte[] priKey; private byte[] pubKey; public byte[] getPriKey() { return priKey; } public void setPriKey(byte[] priKey) { this.priKey = priKey; } public byte[] getPubKey() { return pubKey; } public void setPubKey(byte[] pubKey) { this.pubKey = pubKey; } public void generater() { try { java.security.KeyPairGenerator keygen = java.security.KeyPairGenerator .getInstance("RSA"); SecureRandom secrand = new SecureRandom(); // secrand.setSeed(seed.getBytes()); // 初始化随机产生器,不要调用这个,不安全//seed相同的情况下,每次产生的密钥都一样 keygen.initialize(1024, secrand); KeyPair keys = keygen.genKeyPair(); PublicKey pubkey = keys.getPublic(); PrivateKey prikey = keys.getPrivate(); pubKey = Base64.encodeToByte(pubkey.getEncoded()); priKey = Base64.encodeToByte(prikey.getEncoded()); } catch (java.lang.Exception e) { System.out.println("生成密钥对失败"); e.printStackTrace(); } } }
RASUtil:
package rsa; public class RASUtil { /** * * Description:数字签名 * * @param priKeyByte * @param plainText * @return */ public static byte[] sign(byte[] priKeyByte, String plainText) { try { java.security.spec.PKCS8EncodedKeySpec priPKCS8 = new java.security.spec.PKCS8EncodedKeySpec( Base64.decode(priKeyByte)); java.security.KeyFactory keyf = java.security.KeyFactory.getInstance("RSA"); java.security.PrivateKey prikey = keyf.generatePrivate(priPKCS8); // 用私钥对信息生成数字签名 java.security.Signature signet = java.security.Signature .getInstance("MD5withRSA"); signet.initSign(prikey); signet.update(plainText.getBytes()); byte[] signed = Base64.encodeToByte(signet.sign()); return signed; } catch (java.lang.Exception e) { System.out.println("签名失败"); e.printStackTrace(); } return null; } /** * * Description:校验数字签名,此方法不会抛出任务异常,成功返回true,失败返回false,要求全部参数不能为空 * * @param pubKeyByte * 公钥,base64编码 * @param plainText * 明文 * @param signByte * 数字签名的密文,base64编码 * @return 校验成功返回true 失败返回false */ public static boolean verify(byte[] pubKeyByte, String plainText, byte[] signByte) { try { // 解密由base64编码的公钥,并构造X509EncodedKeySpec对象 java.security.spec.X509EncodedKeySpec bobPubKeySpec = new java.security.spec.X509EncodedKeySpec( Base64.decode(pubKeyByte)); // RSA对称加密算法 java.security.KeyFactory keyFactory = java.security.KeyFactory .getInstance("RSA"); // 取公钥匙对象 java.security.PublicKey pubKey = keyFactory .generatePublic(bobPubKeySpec); // 解密由base64编码的数字签名 byte[] signed = Base64.decode(signByte); java.security.Signature signatureChecker = java.security.Signature .getInstance("MD5withRSA"); signatureChecker.initVerify(pubKey); signatureChecker.update(plainText.getBytes()); // 验证签名是否正常 if (signatureChecker.verify(signed)) return true; else return false; } catch (Throwable e) { System.out.println("校验签名失败"); e.printStackTrace(); return false; } } /** * 公钥加密 * * @param data * @param publicKey * @return * @throws Exception */ public static byte[] encryptByPubKey(byte[] data, byte[] pubKeyByte) { try { // 解密由base64编码的公钥,并构造X509EncodedKeySpec对象 java.security.spec.X509EncodedKeySpec bobPubKeySpec = new java.security.spec.X509EncodedKeySpec( Base64.decode(pubKeyByte)); // RSA对称加密算法 java.security.KeyFactory keyFactory = java.security.KeyFactory .getInstance("RSA"); // 取公钥匙对象 java.security.PublicKey pubKey = keyFactory .generatePublic(bobPubKeySpec); javax.crypto.Cipher cipher = javax.crypto.Cipher.getInstance("RSA"); cipher.init(javax.crypto.Cipher.ENCRYPT_MODE, pubKey); return Base64.encodeToByte(cipher.doFinal(data)); } catch (Exception e) { throw new RuntimeException(e); } } /** * 私钥加密 * * @param data * @param priKeyByte * @return * @throws Exception */ public static byte[] encryptByPriKey(byte[] data, byte[] priKeyByte) { try { java.security.spec.PKCS8EncodedKeySpec priPKCS8 = new java.security.spec.PKCS8EncodedKeySpec( Base64.decode(priKeyByte)); java.security.KeyFactory keyf = java.security.KeyFactory.getInstance("RSA"); java.security.PrivateKey prikey = keyf.generatePrivate(priPKCS8); javax.crypto.Cipher cipher = javax.crypto.Cipher.getInstance("RSA"); cipher.init(javax.crypto.Cipher.ENCRYPT_MODE, prikey); return Base64.encodeToByte(cipher.doFinal(data)); } catch (Exception e) { throw new RuntimeException(e); } } /** * 公钥解密 * * @param data * @param pubKeyByte * @return * @throws Exception */ public static byte[] decryptByPubKey(byte[] data, byte[] pubKeyByte) { try { // 解密由base64编码的公钥,并构造X509EncodedKeySpec对象 java.security.spec.X509EncodedKeySpec bobPubKeySpec = new java.security.spec.X509EncodedKeySpec( Base64.decode(pubKeyByte)); // RSA对称加密算法 java.security.KeyFactory keyFactory = java.security.KeyFactory .getInstance("RSA"); // 取公钥匙对象 java.security.PublicKey pubKey = keyFactory .generatePublic(bobPubKeySpec); javax.crypto.Cipher cipher = javax.crypto.Cipher.getInstance("RSA"); cipher.init(javax.crypto.Cipher.DECRYPT_MODE, pubKey); return Base64.encodeToByte(cipher.doFinal(Base64.decode((data)))); } catch (Exception e) { throw new RuntimeException(e); } } /** * 私钥解密 * * @param data * @param priKeyByte * @return * @throws Exception */ public static byte[] decryptByPriKey(byte[] data, byte[] priKeyByte) { try { java.security.spec.PKCS8EncodedKeySpec priPKCS8 = new java.security.spec.PKCS8EncodedKeySpec( Base64.decode(priKeyByte)); java.security.KeyFactory keyf = java.security.KeyFactory.getInstance("RSA"); java.security.PrivateKey prikey = keyf.generatePrivate(priPKCS8); javax.crypto.Cipher cipher = javax.crypto.Cipher.getInstance("RSA"); cipher.init(javax.crypto.Cipher.DECRYPT_MODE, prikey); return Base64.encodeToByte(cipher.doFinal(Base64.decode(data))); } catch (Exception e) { throw new RuntimeException(e); } } }
Base64:转换一下用了Apache的commons-codec-1.10.jar
package rsa; public class Base64 { public static byte[] encodeToByte(byte[] encoded) { return org.apache.commons.codec.binary.Base64.encodeBase64(encoded); } public static byte[] decode(byte[] plainByte) { return org.apache.commons.codec.binary.Base64.decodeBase64(plainByte); } }
代码引用:http://blog.csdn.net/sunyujia/article/details/2008480
附件commons-codec-1.10.jar
相关推荐
本教程主要讲解如何在C# .NET环境中使用RSA进行公钥加密和私钥解密,以及私钥加密和公钥解密的操作。 首先,让我们了解RSA的基本原理。RSA算法基于两个大素数的乘积,这个乘积作为公钥,而这两个大素数作为私钥。...
在这个示例中,"RSA加密"的压缩包可能包含了Java和C#的完整源代码,用于演示如何在两者之间实现RSA公钥加密和私钥解密的过程。开发者可以通过运行这些示例代码,理解并应用RSA加密解密技术到自己的项目中。
以下是一个简单的Java代码示例,演示了如何生成公钥和私钥对,并使用它们进行加密和解密: ```java import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; ...
在IT行业中,加密技术是确保数据安全的重要手段之一,RSA(Rivest-Shamir-Adleman)算法就是一种广泛使用的非对称加密算法。本文将深入探讨如何在ASP.NET环境中实现RSA加密,并且与PHP和Java进行互通,以及涉及的...
在Java中实现RSA公钥和私钥的生成,通常我们会使用Java Cryptography Extension (JCE) 提供的API,如`java.security.KeyPairGenerator`类。但是,根据你的描述,这里提供的代码是不直接依赖API,而是通过数学计算来...
C# RSA非对称加密 实现私钥加密 公钥解密;可以用于生成授权码。 RSA生成一下随机值,然后都是用BigInteger类字符串跟字节数组互转
总的来说,这个项目展示了如何在C#中使用`System.Numerics.BigInteger`实现RSA加密算法,同时提供了私钥加密和公钥解密的功能,确保了数据的安全性。为了实际应用,你需要理解并掌握RSA算法的原理,以及如何在.NET...
本示例提供了一个RSA加密工具类,用于生成公钥和私钥,并使用它们进行加密和解密操作,这对于保护数据库中的敏感信息,如密码,是非常必要的。 1. **RSA算法原理**: RSA算法基于数论中的大数因子分解难题。其基本...
本例中的Project1.exe可能是一个Delphi编译的示例应用程序,展示了如何在Delphi环境中使用RSA加密和解密。这个程序应该演示了如何生成RSA密钥对,使用公钥加密数据,然后使用私钥解密,反之亦然。在实际应用中,公钥...
Java 中使用公钥加密私钥解密原理实现 License 控制是指在 Java 应用程序中使用公钥加密、私钥解密机制来实现 License 文件的控制。这种机制可以用来限制系统的使用,例如限制试用期、限制用户数量、限制 IP 地址等...
在这个案例中,开发者可能使用了Java的Java Cryptography Extension (JCE) 来实现RSA算法,这是一种非对称加密算法,它基于两个不同的密钥——公钥和私钥——进行加密和解密。 首先,让我们理解公钥和私钥的概念。...
* RSA加密解密:私钥解密,公钥加密。 * RSA数字签名-俗称加签验签:私钥加签,公钥验签。 * RSA加密解密:私钥解密,公钥加密。 * RSA数字签名-俗称加签验签:私钥加签,公钥验签。 * RSA加密解密:私钥...
在C++中实现RSA加密和解密,我们需要用到大数运算库,如GMP(GNU Multiple Precision Arithmetic Library),因为它能处理超过标准整型大小的数字。 **加密过程**: - 输入明文m,0 。 - 使用公钥(e, n),计算c = m...
在给定的"RSA.zip"压缩包中,可能包含了C++代码示例,用于演示如何使用RSA算法进行加密和解密操作,以及如何生成和管理公钥私钥对。文件名"RSA"可能是源代码文件或执行程序。通过学习和理解这些代码,开发者可以更好...
2. **C#实现RSA**:在C#中,`System.Security.Cryptography.RSACryptoServiceProvider`类提供了RSA加密和解密的功能。你可以通过这个类创建、保存和加载密钥对,然后使用`Encrypt`和`Decrypt`方法进行加解密操作。 ...
公钥加密私钥解密是基于非对称加密算法的一种实现方式。这种加密方法使用一对密钥——公钥和私钥。其中,公钥可以公开给任何人使用,而私钥则必须保密,只有密钥的所有者才能掌握。具体工作流程如下: 1. **发送方...
在C#中,我们可以使用.NET Framework提供的System.Security.Cryptography命名空间中的RSACryptoServiceProvider类来实现RSA加密和解密。首先,我们需要生成一对公钥和私钥。这可以通过调用RSACryptoServiceProvider...
"Go-gorsa"是一个专门为Go语言设计的安全库,它专注于RSA(Rivest-Shamir-Adleman)加密算法的实现,允许用户进行公钥加密和私钥解密,以及公钥解密和私钥加密的操作。这一特性使得gorsa在确保信息安全方面具有很高...
RSA算法是一种非对称加密算法,它是现代密码学的基石之一,广泛应用于数据加密、数字签名和密钥交换等领域。该算法基于数论中的大数因子分解难题,由Ron Rivest、Adi Shamir和Leonard Adleman在1978年提出,因此得名...
JavaRSA生成公钥私钥及加解密是Java编程中涉及密码学的重要实践。RSA是一种非对称加密算法,由Ron Rivest、Adi Shamir和Leonard Adleman在1977年提出,因其发明者的名字首字母命名。在Java中,我们可以使用Java ...