您可以忽略更新 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");
}
}
}