#java #spring
#java #spring
Вопрос:
У меня есть класс пользователя, сущность, и он должен записать имя пользователя и адрес электронной почты в зашифрованном виде с помощью асимметричного ключа (RSA) размером 2048.
Информация будет зашифрована с помощью открытого ключа клиента, и он будет расшифровывать, используя свой закрытый ключ.
@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);
}
}
Ответ №1:
Вы пытаетесь сгенерировать ключи RSA, которые можно использовать для подписи, но не для шифрования, при создании экземпляра keypairgenerator и шифровании с помощью «SHA256withRSA».
Вам нужно изменить 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);
}
}
Комментарии:
1. Спасибо за ответ. Мне нужно, чтобы мой пользователь получал этот открытый ключ, и при отправке данных для регистрации, например, он также отправляет мне этот ключ, и я выполняю шифрование. Итак, я отправил
keypair.getpublickey()
бы контроллер via или ресурс? Прежде чем он отправит мне данные для шифрования?2. Я не совсем уверен, каков ваш рабочий процесс. Допустим, у нас есть ОТПРАВИТЕЛЬ и ПОЛУЧАТЕЛЬ. ПОЛУЧАТЕЛЬ отправляет свой открытый ключ ОТПРАВИТЕЛЮ. ОТПРАВИТЕЛЬ шифрует свои секретные данные с помощью открытого ключа, полученного от ПОЛУЧАТЕЛЯ. ОТПРАВИТЕЛЬ отправляет свой зашифрованный текст ПОЛУЧАТЕЛЮ. Только ПОЛУЧАТЕЛЬ может расшифровать секретные данные с помощью своего закрытого ключа. Вам решать, как вы отправляете открытый ключ отправителю (существует несколько способов форматирования для кодирования ключа и последующего восстановления открытого ключа).
3. Мой пользователь должен получить открытый ключ. Чтобы при отправке его данных я использовал этот открытый ключ, полученный им ранее, для шифрования его данных. Итак, мой вопрос в том, если я отправлю ему это
getPublicKey()
, сработает ли это шифрование, которое будет позже? мой открытый ключ не обязательно должен быть исключительно для этого пользователя.