0

您可以忽略更新 3 之前的所有内容,其余内容仅供参考,了解是什么让我达到了我的目的。

好的,所以我对编码很陌生,我想解决一些功能问题。我一直在研究一个 RSA 密码系统,它将生成一个密钥对并使用所述密钥对加密/解密消息。到目前为止,我已经弄清楚了如何为每个键生成模数和指数,以及如何让每个键在编码/解码时正常工作。但是我正在为每个密钥分别处理原始模数和指数,我不知道 RSA 密钥的格式应该如何看待。所以,我想知道如何创建格式正确的 RSA 密钥(我知道我必须使用 javax.crypto,但我不太明白如何)。我更喜欢的是,如果我可以采用我已经拥有的代码(如下所示)并添加一个采用模数和指数并将它们组合成适当键的部分。哦,我 我希望能够从密钥中找到模数和指数,以便我可以将其添加到我的加密/解密代码部分。此外,我还有作为模数和指数生成的公钥。

关于问题的更新:好的,感谢 ArtJom B。我一直在查看 java 中的安全库。但是现在我遇到了一个新问题,我完全迷失了。我编辑了我的代码,以便它(希望)应该获取每个键的部分并使用 keyfactory 将它们变成关键对象。但我不断收到同样的错误。下面是新程序的代码,也是我不断收到的错误。我真的不在乎这是否意味着我正在重新设计算法的实现,我只想让我的代码正常运行。

更新 2:好的,所以 GregS 将我与异常相关联。伟大的!代码现在将编译并运行。但存在一些问题。A)私钥只显示为[这部分是固定的],我不知道我能用它做什么...... B)公钥仍然作为模数和公共指数分开,我认为不是应该这样做

小更新:哦,我想通了,我不小心把私有指数放在了模数区域,而他把公共指数放在了 RSAPublicKeySpec ctor 的私有指数区域。但是问题A和B仍然存在......

最终编辑:好的,所以问题开始变得太宽泛了。我正在改变它的初衷。我最初的问题得到了回答,因此有效的代码如下。我生成一个密钥对象,然后获取其编码的 base64。

这是新代码:

    import javax.xml.bind.DatatypeConverter;
import java.util.Base64;
import java.math.*;
import java.util.Scanner;
import java.security.spec.KeySpec;
import java.security.*;
import javax.crypto.Cipher;
import java.security.GeneralSecurityException;
import java.security.KeyFactory;
import java.security.spec.RSAPublicKeySpec;
import java.security.spec.RSAPrivateKeySpec;
import java.security.Provider;
import java.security.Key;
import java.security.Security;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.security.InvalidKeyException;
import java.security.spec.RSAPrivateCrtKeySpec;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.interfaces.RSAPrivateCrtKey;
import java.security.interfaces.RSAPublicKey;

public class RSAcryptprop {

public static void main(String[] args){
        try{
        Scanner reader = new Scanner(System.in);
        KeyFactory kF = KeyFactory.getInstance("RSA"); 

        BigInteger valP, valQ, valN, totN, valE, valD, valC, valM, valMD, valsub, valDD, valED, valND, valQE, valPE, valCrtC;

        String valPt, valQt, valEt, valMt;

        //here's the set of starting values, two prime numbers of similar bit length


        System.out.println("Value of P?:");
        valPt = reader.next();
        valP = new BigInteger(valPt);
        System.out.println("Value of Q?:");
        valQt = reader.next();
        valQ = new BigInteger(valQt);


        //then find the value of N and the totient of N

        valN= valQ.multiply(valP);
        valsub = new BigInteger("1");

totN= (valQ.subtract(valsub)).multiply(valP.subtract(valsub));


        System.out.println("Totient of N:" + totN.toString(10));
        System.out.println("Value of E? (must be coprime to totient of N):");
        //E is a number coprime to the totient of N

        valEt = reader.next();
        valE = new BigInteger(valEt);



        //N and E are the public key
        RSAPublicKeySpec pubKeyS;
        pubKeyS = new RSAPublicKeySpec(valN,valE);
        PublicKey pubKey = kF.generatePublic(pubKeyS);
        String pubKeyProp = DatatypeConverter.printBase64Binary(pubKey.getEncoded());
        byte[] encodedPubKey = Base64.getDecoder().decode(pubKeyProp);  

        //then I find the modular inverse of the totient modulus E.
        valD = valE.modInverse(totN);




        valPE = valD.mod(valP.subtract(valsub));
        valQE = valD.mod(valQ.subtract(valsub));
        valCrtC = (valQ.subtract(valsub)).mod(valP);
        //N and D are the private key
        RSAPrivateCrtKeySpec privKeyS;
        privKeyS = new RSAPrivateCrtKeySpec(valN, valE, valD, valP, valQ, valPE, valQE, valCrtC);
        PrivateKey privKey = kF.generatePrivate(privKeyS);
        String privKeyProp = DatatypeConverter.printBase64Binary(privKey.getEncoded());
        byte[] encodedPrivKey = Base64.getDecoder().decode(privKeyProp);

        System.out.println("Value of the message?:");
        valMt = reader.next();

        //M is the message that is being encrypted

        valM = new BigInteger(valMt);



        //now for encryption/decryption
        RSAPublicKeySpec pubKeySD;      
        pubKeySD = kF.getKeySpec(pubKey,RSAPublicKeySpec.class);
        valND = pubKeySD.getModulus();
        RSAPrivateCrtKeySpec privKeySD;
        privKeySD = kF.getKeySpec(privKey,RSAPrivateCrtKeySpec.class);
        valDD = privKeySD.getPrivateExponent();


        //C is the encrypted form of the message

        valED = pubKeySD.getPublicExponent();

        valC= valM.modPow(valED,valND); 

        //now to decode the value of M from the value of C
        valMD = valC.modPow(valDD,valND);


        //M is the message, C is the encoded form, n and e are the public key, n and d are the private key


        System.out.println("Message being encrypted: " + valM);

        System.out.println("Encrypted form of message: " + valC);

        System.out.println("Message after going through decrypting: " + valMD);
        System.out.println();
        System.out.println("Proper Private Key:");
        System.out.println("-----BEGIN RSA PRIVATE KEY-----");
        System.out.println(privKeyProp);
        System.out.println("-----END RSA PRIVATE KEY-----");
        System.out.println("Proper Public Key:");
        System.out.println("-----BEGIN RSA PUBLIC KEY-----");
        System.out.println(pubKeyProp);
        System.out.println("-----END RSA PUBLIC KEY-----");

        }
        catch(NoSuchAlgorithmException e){
        System.err.println("algorithm error");
        }
        catch(InvalidKeySpecException e){
        System.err.println("keyspec error");
        }

    }

}
4

0 回答 0