Initial commit: SSH Manager (backend + frontend)
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
package com.sshmanager.service;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.spec.GCMParameterSpec;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Base64;
|
||||
|
||||
@Service
|
||||
public class EncryptionService {
|
||||
|
||||
private static final int GCM_IV_LENGTH = 12;
|
||||
private static final int GCM_TAG_LENGTH = 128;
|
||||
private static final String ALGORITHM = "AES/GCM/NoPadding";
|
||||
|
||||
private final byte[] keyBytes;
|
||||
|
||||
public EncryptionService(@Value("${sshmanager.encryption-key}") String base64Key) {
|
||||
this.keyBytes = Base64.getDecoder().decode(base64Key);
|
||||
if (keyBytes.length != 32) {
|
||||
throw new IllegalArgumentException("Encryption key must be 32 bytes (256 bits)");
|
||||
}
|
||||
}
|
||||
|
||||
public String encrypt(String plainText) {
|
||||
if (plainText == null || plainText.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
byte[] iv = new byte[GCM_IV_LENGTH];
|
||||
new SecureRandom().nextBytes(iv);
|
||||
|
||||
SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");
|
||||
GCMParameterSpec gcmSpec = new GCMParameterSpec(GCM_TAG_LENGTH, iv);
|
||||
|
||||
Cipher cipher = Cipher.getInstance(ALGORITHM);
|
||||
cipher.init(Cipher.ENCRYPT_MODE, keySpec, gcmSpec);
|
||||
byte[] encrypted = cipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8));
|
||||
|
||||
byte[] combined = new byte[iv.length + encrypted.length];
|
||||
System.arraycopy(iv, 0, combined, 0, iv.length);
|
||||
System.arraycopy(encrypted, 0, combined, iv.length, encrypted.length);
|
||||
|
||||
return Base64.getEncoder().encodeToString(combined);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Encryption failed", e);
|
||||
}
|
||||
}
|
||||
|
||||
public String decrypt(String encryptedText) {
|
||||
if (encryptedText == null || encryptedText.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
byte[] combined = Base64.getDecoder().decode(encryptedText);
|
||||
byte[] iv = new byte[GCM_IV_LENGTH];
|
||||
byte[] encrypted = new byte[combined.length - GCM_IV_LENGTH];
|
||||
System.arraycopy(combined, 0, iv, 0, iv.length);
|
||||
System.arraycopy(combined, iv.length, encrypted, 0, encrypted.length);
|
||||
|
||||
SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");
|
||||
GCMParameterSpec gcmSpec = new GCMParameterSpec(GCM_TAG_LENGTH, iv);
|
||||
|
||||
Cipher cipher = Cipher.getInstance(ALGORITHM);
|
||||
cipher.init(Cipher.DECRYPT_MODE, keySpec, gcmSpec);
|
||||
byte[] decrypted = cipher.doFinal(encrypted);
|
||||
|
||||
return new String(decrypted, StandardCharsets.UTF_8);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Decryption failed", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user