使用Java的RSA加密/解密
我正在做一个简单的程序来使用Java中的RSA算法进行加密/解密。 我创建一个密码对象如下:
//Create a Cipher object Cipher rsaCipher = Cipher.getInstance("RSA/ECB/NoPadding");
我通过调用加密函数来进行加密:
String cipher=encrypt(textByte, pair, rsaCipher); System.out.println("The Encryption using RSA Algorithm : "+cipher);
并解密为:
//Decryption String plain=decrypt(Base64.decodeBase64(cipher),pair, rsaCipher); System.out.println("The Decryption using RSA Algorithm : "+plain);
当我显示输出时,解密输出在原始文本之前返回一个长空格:
但是,当我编辑用于创建Cipher对象的代码时://创建一个密码对象Cipher rsaCipher = Cipher.getInstance(“RSA”);
即,删除操作模式和填充参数,问题得到解决,输出变为:
问题出在哪儿。 在第一种情况下(当空间出现时),我指定了NoPadding? 为什么空格出现在解密的消息中? 即使我使用填充,我预计这不应该发生。
编辑:这是加密和解密方法:
public static String encrypt(byte[] textBytes, KeyPair pair, Cipher rsaCipher) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException { //get the public key PublicKey pk=pair.getPublic(); //Initialize the cipher for encryption. Use the public key. rsaCipher.init(Cipher.ENCRYPT_MODE, pk); //Perform the encryption using doFinal byte[] encByte = rsaCipher.doFinal(textBytes); // converts to base64 for easier display. byte[] base64Cipher = Base64.encodeBase64(encByte); return new String(base64Cipher); }//end encrypt public static String decrypt(byte[] cipherBytes, KeyPair pair, Cipher rsaCipher) throws IllegalBlockSizeException, BadPaddingException, InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException { //get the public key PrivateKey pvk=pair.getPrivate(); //Create a Cipher object //Cipher rsaCipher = Cipher.getInstance("RSA/ECB/NoPadding"); //Initialize the cipher for encryption. Use the public key. rsaCipher.init(Cipher.DECRYPT_MODE, pvk); //Perform the encryption using doFinal byte[] decByte = rsaCipher.doFinal(cipherBytes); return new String(decByte); }//end decrypt
你的问题确实与填充。 实际上,需要某种填充(PKCS#1 1.5或OAEP填充)才能实现安全的RSAfunction。 此外,需要找到加密纯文本的开头和结尾。
RSA的模幂运算使用大整数执行。 然后将这些操作的结果表示为八位字符串。 这些八位字节串基本上是大端,无符号,整数的固定长度表示。 这些整数用00
值字节填充(这在RSA标准中称为I2OS原语)。 所以你看到的是模幂运算的结果, 00
填充仍然存在。
长话短说,总是使用填充方案。 如今,OAEP将更为可取。 将其与混合加密方案一起使用,或使用更高级别的容器格式,如CMS或PGP。
RSA的模幂运算使用大整数执行。 然后将这些操作的结果表示为八位字符串。 这些八位字节串基本上是大端,无符号,整数的固定长度表示。 这些整数用00值字节填充(这在RSA标准中称为I2OS原语)。 所以你看到的是模幂运算的结果,00填充仍然存在。
//This is a complete encryption and decryption module using //Algorithm: JWEAlgorithm.RSA_OAEP_256 //Encryption Method: A128CBC_HS256 public static String encrypt(String text) throws Exception { // Set the plain text Payload payload = new Payload(text); // Create the header JWEHeader header = new JWEHeader(JWEAlgorithm.RSA_OAEP_256, EncryptionMethod.A128CBC_HS256); // Create the JWE object and encrypt it JWEObject jweObject = new JWEObject(header, payload); jweObject.encrypt(new RSAEncrypter(getPublicKey())); // Serialise to compact JOSE form... String jweString = jweObject.serialize(); LOG.info("Generated Encrypted Key : {}", jweString); return jweString; } public static String decrypt(String text) throws Exception { // Parse into JWE object... JWEObject jweObject = JWEObject.parse(text); jweObject.decrypt(new RSADecrypter(getPrivateKey())); // Get the plain text Payload payload = jweObject.getPayload(); System.out.println(payload.toString()); return payload.toString(); } private static RSAPublicKey getPublicKey() throws Exception { String filename = "/home/vaibhav/Setups/cert/pub.der"; File f = new File(filename); FileInputStream fis = new FileInputStream(f); DataInputStream dis = new DataInputStream(fis); byte[] keyBytes = new byte[(int)f.length()]; dis.readFully(keyBytes); dis.close(); X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes); KeyFactory kf = KeyFactory.getInstance("RSA"); return (RSAPublicKey) kf.generatePublic(spec); } private static RSAPrivateKey getPrivateKey() throws Exception { String filename = "/home/vaibhav/Setups/cert/private.pkcs8"; File f = new File(filename); FileInputStream fis = new FileInputStream(f); DataInputStream dis = new DataInputStream(fis); byte[] keyBytes = new byte[(int)f.length()]; dis.readFully(keyBytes); dis.close(); PKCS8EncodedKeySpec spec1 = new PKCS8EncodedKeySpec(keyBytes); KeyFactory kf = KeyFactory.getInstance("RSA"); return (RSAPrivateKey) kf.generatePrivate(spec1); }
希望这可以帮助! 🙂
import java.util.*; import java.math.*; class RSA { public static void main(String args[]) { BigInteger one, p, q, E, D, n,P,Q; Scanner s = new Scanner(System.in); Scanner t = new Scanner(System.in); System.out.println("Enter A's prime number!"); p = s.nextBigInteger(); System.out.println("Enter B's prime number!"); q = s.nextBigInteger(); n = p.multiply(q); P = p.subtract(BigInteger.ONE); Q = q.subtract(BigInteger.ONE); int x = 0; do { System.out.println("Enter Public key "); E =s.nextBigInteger(); if(((P.gcd(E)).equals(BigInteger.ONE))&&((Q.gcd(E)).equals(BigInteger.ONE))) {x++;} }while(x==0); for(int i = 1;;i++) { D=new BigInteger(String.valueOf(i)); if(((D.multiply(E)).mod(P.multiply(Q))).equals(BigInteger.ONE)) break; } System.out.println("Enter Plain text!"); String in = "", out ="", text = t.nextLine(); for(int i = 0;i < text.length();i++){ BigInteger T = new BigInteger(String.valueOf((int)(text.charAt(i)))), O, TF; O = T.modPow(E,n); out += (char)O.intValue(); TF = O.modPow(D,n); in += (char)TF.intValue(); } System.out.println("Encrypted text : " + out); System.out.println("Decrypted text : "+ in); } }
- 如何使用Bouncy Castle编辑Java中的密码套件列表
- 如何使用java PKCS#12密钥库中的证书来加密和解密文件?
- 从字节数组创建PrivateKey
- 如何在openssl生成的java中使用.key和.crt文件?
- 如何从pem文件加载公共证书?
- 解密(使用PHP)Java加密(PBEWithMD5AndDES)
- 将SubjectPublicKeyInfo格式的公钥转换为RSAPublicKey格式java
- java.lang.IllegalArgumentException:string curve25519 not a OID bouncycastle 1.52
- 如何解密签名的pgp加密文件?