java - 我如何拥有自己的公钥来加密数据?
问题描述
我有一个用户类,一个实体,它必须使用大小为 2048 的非对称密钥 (RSA) 以加密形式写入用户名和电子邮件。
信息将使用客户的公钥加密,他将使用他的私钥解密。
@Entity
public class Usuario implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String nome;
private String email;
@JsonBackReference
@ManyToMany
@JoinTable(name = "USUARIO_DIGITO", joinColumns = @JoinColumn(name = "usuario_id"), inverseJoinColumns = @JoinColumn(name = "digito_id"))
private Set<DigitoUnico> resultadosDigitoUnico;
....
getters and setters
}
在用户服务中,我调用为加密和解密创建的方法。
@Service
public class UsuarioService implements IUsuarioService {
@Autowired
private IUsuarioRepository usuarioRepository;
....
public Usuario adicionar(Usuario usuario) {
usuario.setId(null);
usuario.setResultadosDigitoUnico(null);
try {
return usuarioRepository.save(encriptarDadosUsuario(usuario));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
private Usuario encriptarDadosUsuario(Usuario usuario) throws Exception {
usuario.setEmail(EncriptaDadosUsuario.encriptar(usuario.getEmail(), EncriptaDadosUsuario.gerarParDeChaves().getPublic()));
usuario.setNome(EncriptaDadosUsuario.encriptar(usuario.getNome(), EncriptaDadosUsuario.gerarParDeChaves().getPublic()));
return usuario;
}
private Usuario decriptarDadosUsuario(Usuario usuario) throws Exception{
usuario.setEmail(EncriptaDadosUsuario.decriptar(usuario.getEmail(),EncriptaDadosUsuario.gerarParDeChaves().getPrivate()));
usuario.setNome(EncriptaDadosUsuario.decriptar(usuario.getNome(),EncriptaDadosUsuario.gerarParDeChaves().getPrivate()));
return usuario;
}
}
但是,我必须创建一个端点来将此用户的公钥发送到客户端以进行加密。
我怎样才能拥有我的公钥,并将其用于此加密和解密?
在我的班级下面进行加密:
public class EncriptaDadosUsuario {
public static KeyPair gerarParDeChaves() throws Exception {
KeyPairGenerator generator = KeyPairGenerator.getInstance("SHA256withRSA");
generator.initialize(2048, new SecureRandom());
KeyPair pair = generator.generateKeyPair();
return pair;
}
public static String encriptar(String plainText, PublicKey publicKey) throws Exception {
Cipher encryptCipher = Cipher.getInstance("SHA256withRSA");
encryptCipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] cipherText = encryptCipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8));
return Base64.getEncoder().encodeToString(cipherText);
}
public static String decriptar(String cipherText, PrivateKey privateKey) throws Exception {
byte[] bytes = Base64.getDecoder().decode(cipherText);
Cipher decriptCipher = Cipher.getInstance("SHA256withRSA");
decriptCipher.init(Cipher.DECRYPT_MODE, privateKey);
return new String(decriptCipher.doFinal(bytes), StandardCharsets.UTF_8);
}
}
解决方案
在使用“ SHA256withRSA ”实例化密钥对生成器和密码时,您尝试生成可用于签名但不能用于加密的 RSA 密钥。
您需要将 KeyPairGenerator 更改为“RSA”,将密码更改为“RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING”[或您的 Java 上的其他可用密码],以使您的代码运行。
您可以在下面找到包含更正的部分代码和一个小示例,该示例对电子邮件地址进行加密,然后将密文解密为解密后的文本。
请注意,此示例代码没有异常处理,仅用于教育目的。
输出:
How do I have my own public key to encrypt data
ciphertext: lVN6XLO7LxMASVifq2J1/T8Hv40AUeOml3+MjA6u+mKv1EcJHQO7gbZpMCrhO1fzo3s5tGRQl38iumMDqLBp+ApxQkPKeVVU99oOeuzYZb9fwyBH1/b4AEC1UDdFBWwH6rN/MuG17FyBrq/JR64upcM79gITdrIywvd32gYCd+XrGcGIxDoDGufQ1iqjjOihnRdYkYQDhUNEhi3clTz+ZDJ1EqMZmfc+v9Fsnsit2q9wbO3C33Hjbj/gY8AIMOpE7KYGupnpvR+WQk1DvmqiDoIDNfweRvwqF9m+7AUldAxxmjPN0C/WFmYPfZHUFSBK/0+8Ix5pDNw4l3C8thWKeg==
decryptedtext: myEmail@stackoverflow.com
代码:
import javax.crypto.Cipher;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.util.Base64;
public class Main {
public static void main(String[] args) throws Exception {
System.out.println("How do I have my own public key to encrypt data");
// string to encrypt
String plaintext = "myEmail@stackoverflow.com";
// keypair generation
KeyPair keyPair = gerarParDeChaves();
// encryption
PublicKey publicKey = keyPair.getPublic();
String ciphertext = encriptar(plaintext, publicKey);
System.out.println("ciphertext: " + ciphertext);
// decryption
PrivateKey privateKey = keyPair.getPrivate();
String decryptedtext = decriptar(ciphertext, privateKey);
System.out.println("decryptedtext: " + decryptedtext);
}
public static KeyPair gerarParDeChaves() throws Exception {
//KeyPairGenerator generator = KeyPairGenerator.getInstance("SHA256withRSA"); // used for signatures
KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");
generator.initialize(2048, new SecureRandom());
KeyPair pair = generator.generateKeyPair();
return pair;
}
public static String encriptar(String plainText, PublicKey publicKey) throws Exception {
//Cipher encryptCipher = Cipher.getInstance("SHA256withRSA"); // used for signatures
Cipher encryptCipher = Cipher.getInstance("RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING");
encryptCipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] cipherText = encryptCipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8));
return Base64.getEncoder().encodeToString(cipherText);
}
public static String decriptar(String cipherText, PrivateKey privateKey) throws Exception {
byte[] bytes = Base64.getDecoder().decode(cipherText);
//Cipher decriptCipher = Cipher.getInstance("SHA256withRSA"); // used for signatures
Cipher decriptCipher = Cipher.getInstance("RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING");
decriptCipher.init(Cipher.DECRYPT_MODE, privateKey);
return new String(decriptCipher.doFinal(bytes), StandardCharsets.UTF_8);
}
}
推荐阅读
- java - 我试图计算一个 int 数组中最长的序列,该数组总和为非负数(JAVA)......数组在 -1,0,1 范围内
- javascript - Javascript 不执行
- php - 从数组php中删除键和值
- xml - 压缩的 XML 文件在 BBEdit 中显示正常,但在 Sublime Text 中不显示
- javascript - PM2 Digital Ocean Server 无法连接
- ansible-awx - 从 AWX 1.0.6 升级到 1.0.7
- apache-camel - Camel json-validator 抛出 Stream closed 异常
- docker - Docker 容器在挂载中收到权限被拒绝
- meteor - 用于传递变量的 GraphQL 查询参数语法
- debugging - fmt.Scanln 的调试问题