【问题标题】:RSA implementation using java使用java实现RSA
【发布时间】:2019-10-04 14:08:59
【问题描述】:

我在 java 中实现 RSA 我遇到了下面给出的代码,它在解密明文后以数字形式显示明文,但我想要我输入的简单英文。我不想使用 java api。

TestRsa.Java

import java.io.IOException;
import java.math.BigInteger;
import java.util.Random;

public class TestRsa {

    private BigInteger p, q;
    private BigInteger n;
    private BigInteger PhiN;
    private BigInteger e, d;

    public TestRsa() {
        initialize();
    }

    public void initialize() {
        int SIZE = 512;
        /* Step 1: Select two large prime numbers. Say p and q. */
        p = new BigInteger(SIZE, 15, new Random());
        q = new BigInteger(SIZE, 15, new Random());
        /* Step 2: Calculate n = p.q */
        n = p.multiply(q);
        /* Step 3: Calculate ø(n) = (p - 1).(q - 1) */
        PhiN = p.subtract(BigInteger.valueOf(1));
        PhiN = PhiN.multiply(q.subtract(BigInteger.valueOf(1)));
        /* Step 4: Find e such that gcd(e, ø(n)) = 1 ; 1 < e < ø(n) */
        do {
            e = new BigInteger(2 * SIZE, new Random());
        } while ((e.compareTo(PhiN) != 1)
                || (e.gcd(PhiN).compareTo(BigInteger.valueOf(1)) != 0));
        /* Step 5: Calculate d such that e.d = 1 (mod ø(n)) */
        d = e.modInverse(PhiN);
    }

    public BigInteger encrypt(BigInteger plaintext) {
        return plaintext.modPow(e, n);
    }

    public BigInteger decrypt(BigInteger ciphertext) {
        return ciphertext.modPow(d, n);
    }

    public static void main(String[] args) throws IOException {
        TestRsa app = new TestRsa();
        int plaintext;
        System.out.println("Enter any character : ");
        plaintext = System.in.read();
        BigInteger bplaintext, bciphertext;
        bplaintext = BigInteger.valueOf((long) plaintext);
        bciphertext = app.encrypt(bplaintext);
        System.out.println("Plaintext : " + bplaintext.toString());
        System.out.println("Ciphertext : " + bciphertext.toString());
        bplaintext = app.decrypt(bciphertext);
        System.out.println("After Decryption Plaintext : "
                + bplaintext.toString());
    }
}

【问题讨论】:

  • -1 用于发布超过 50% 空行的代码。如果您希望人们阅读您的代码,则由您自己决定是否使其具有可读性。

标签: java rsa


【解决方案1】:

我的 RSA 课程:

package com.infovale.cripto;

import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Arrays;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;

public class RSA {


static String kPublic = "";
static String kPrivate = "";

public RSA()
{

}


public String Encrypt(String plain) throws NoSuchAlgorithmException,
        NoSuchPaddingException, InvalidKeyException,
        IllegalBlockSizeException, BadPaddingException {

    String encrypted;
    byte[] encryptedBytes;      

    KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
    kpg.initialize(1024);
    KeyPair kp = kpg.genKeyPair();

    PublicKey publicKey = kp.getPublic();
    PrivateKey privateKey = kp.getPrivate();

    byte[] publicKeyBytes = publicKey.getEncoded();
    byte[] privateKeyBytes = privateKey.getEncoded();

    kPublic = bytesToString(publicKeyBytes);
    kPrivate = bytesToString(privateKeyBytes);

    Cipher cipher = Cipher.getInstance("RSA");
    cipher.init(Cipher.ENCRYPT_MODE, publicKey);
    encryptedBytes = cipher.doFinal(plain.getBytes());

    encrypted = bytesToString(encryptedBytes);
    return encrypted;

}

public String Decrypt(String result) throws NoSuchAlgorithmException,
        NoSuchPaddingException, InvalidKeyException,
        IllegalBlockSizeException, BadPaddingException {

    byte[] decryptedBytes;

    byte[] byteKeyPrivate = stringToBytes(kPrivate);

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

    PrivateKey privateKey = null;
    try {

        privateKey = kf.generatePrivate(new PKCS8EncodedKeySpec(byteKeyPrivate));

    } catch (InvalidKeySpecException e) {
        e.printStackTrace();
    }

    String decrypted;

    Cipher cipher = Cipher.getInstance("RSA");
    cipher.init(Cipher.DECRYPT_MODE, privateKey);
    decryptedBytes = cipher.doFinal(stringToBytes(result));
    decrypted = new String(decryptedBytes);
    return decrypted;

}

public String bytesToString(byte[] b) {
    byte[] b2 = new byte[b.length + 1];
    b2[0] = 1;
    System.arraycopy(b, 0, b2, 1, b.length);
    return new BigInteger(b2).toString(36);
}

public byte[] stringToBytes(String s) {
    byte[] b2 = new BigInteger(s, 36).toByteArray();
    return Arrays.copyOfRange(b2, 1, b2.length);
}
}

【讨论】:

  • 操作员写道:“我不想使用 java api”
【解决方案2】:

试试这些行:

System.out.println("Plaintext : " +  new String(bplaintext.toByteArray() ) );
System.out.println("Ciphertext : " +  new String(bciphertext.toByteArray() ) );
bplaintext = app.decrypt(bciphertext);
        System.out.println("After Decryption Plaintext : " + new String(bplaintext.toByteArray() ) );

【讨论】:

    【解决方案3】:

    我稍微编辑了 Elton Da Costa 的课程,添加了将公钥从 String 转换为 PublicKey 类的功能。因为这个类的用户最终可能希望将公钥提供给第三方来加密消息,并保留自己的私钥以进行解密。

                package com.custom.util;
    
                import java.math.BigInteger;
                import java.security.InvalidKeyException;
                import java.security.KeyFactory;
                import java.security.KeyPair;
                import java.security.KeyPairGenerator;
                import java.security.NoSuchAlgorithmException;
                import java.security.PrivateKey;
                import java.security.PublicKey;
                import java.security.spec.InvalidKeySpecException;
                import java.security.spec.PKCS8EncodedKeySpec;
                import java.security.spec.X509EncodedKeySpec;
                import java.util.Arrays;
    
                import javax.crypto.BadPaddingException;
                import javax.crypto.Cipher;
                import javax.crypto.IllegalBlockSizeException;
                import javax.crypto.NoSuchPaddingException;
    
                public class RSA {
    
                    static String kPublic = "";
                    static String kPrivate = "";
    
                    public RSA() {
    
                    }
    
                    public class KeyPairStrings {
                        private String pubKey;
                        private String privKey;
    
                        public String getPubKey() {
                            return pubKey;
                        }
    
                        public String getPrivKey() {
                            return privKey;
                        }
    
                        @Override
                        public String toString() {
                            return "KeyPairStrings [pubKey=" + pubKey + ", privKey=" + privKey + "]";
                        }
    
    
    
                    }
    
                public KeyPairStrings getKeyPair() throws NoSuchAlgorithmException{
    
                    KeyPairStrings keyPairStrings = new RSA.KeyPairStrings();
    
                    KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
                    kpg.initialize(1024);
                    KeyPair kp = kpg.genKeyPair();
    
                    PublicKey publicKey = kp.getPublic();
                    PrivateKey privateKey = kp.getPrivate();
    
                    byte[] publicKeyBytes = publicKey.getEncoded();
                    byte[] privateKeyBytes = privateKey.getEncoded();
    
                    keyPairStrings.pubKey = bytesToString(publicKeyBytes);
                    keyPairStrings.privKey = bytesToString(privateKeyBytes);
    
                    return keyPairStrings ;
                }
    
    
                public String encrypt(String text , String pubKey) throws NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, InvalidKeyException{
    
                    byte[] pubKeyByte = stringToBytes(pubKey) ;
    
                    KeyFactory kf = KeyFactory.getInstance("RSA");
    
                    PublicKey publicKey = null;
                    try {
    
                        publicKey = kf.generatePublic(new X509EncodedKeySpec(pubKeyByte));
    
                    } catch (InvalidKeySpecException e) {
                        e.printStackTrace();
                    }
    
                    Cipher cipher = Cipher.getInstance("RSA");
                    cipher.init(Cipher.ENCRYPT_MODE, publicKey );
                    byte[] encryptedBytes = cipher.doFinal(text.getBytes());
    
                    String encrypted = bytesToString(encryptedBytes);
    
                    return encrypted;
                }
    
                public String decrypt(String encryptedText , String privKey) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException{
    
                    byte[] privKeyByte = stringToBytes(privKey) ;
    
                    KeyFactory kf = KeyFactory.getInstance("RSA");
    
                    PrivateKey privateKey = null;
                    try {
    
                        privateKey = kf.generatePrivate(new PKCS8EncodedKeySpec(privKeyByte));
    
                    } catch (InvalidKeySpecException e) {
                        e.printStackTrace();
                    }
    
                    String decrypted;
    
                    Cipher cipher = Cipher.getInstance("RSA");
                    cipher.init(Cipher.DECRYPT_MODE, privateKey);
                    byte[] decryptedBytes = cipher.doFinal(stringToBytes(encryptedText));
                    decrypted = new String(decryptedBytes);
                    return decrypted;
                }
    
    
                public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeyException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException {
    
                    String text = "hello" ;
    
                    RSA rsa = new RSA();
    
                    KeyPairStrings keyPairStrings =  rsa.getKeyPair() ;
    
                    System.out.println(keyPairStrings);
    
                    String encrypted  = rsa.encrypt(text, keyPairStrings.getPubKey());
    
                    System.out.println("encrypted : "+encrypted);   
    
                    String textResult = rsa.decrypt(encrypted, keyPairStrings.getPrivKey());
    
                    System.out.println("textResult : "+textResult);
    
                }
    
    
    
                    public static String bytesToString(byte[] b) {
                        byte[] b2 = new byte[b.length + 1];
                        b2[0] = 1;
                        System.arraycopy(b, 0, b2, 1, b.length);
                        return new BigInteger(b2).toString(36);
                    }
    
                    public byte[] stringToBytes(String s) {
                        byte[] b2 = new BigInteger(s, 36).toByteArray();
                        return Arrays.copyOfRange(b2, 1, b2.length);
                    }
                }
    

    【讨论】:

      【解决方案4】:

      而不是这个(它只读取第一个字符):

      int plaintext;
      plaintext = System.in.read();
      bplaintext = BigInteger.valueOf((long) plaintext);
      

      使用这个(读取字符串):

      byte[] plaintext;
      plaintext = new Scanner(System.in).nextLine().getBytes();
      bplaintext = new BigInteger(plaintext);
      

      然后将这个添加到末尾(将解密的 BigInteger 转换回字符串)

      System.out.println("Original String: " + new String(bplaintext.toByteArray()));
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-12-20
        • 2011-02-23
        • 2011-02-12
        • 2014-08-12
        • 2019-05-07
        • 2021-10-29
        • 2023-03-15
        • 1970-01-01
        相关资源
        最近更新 更多