ecc加密 java实现,使用ECC Curve25519在Java中加密/解密数据

加密Android设备上的文件的关键是永远不存储密钥 . 为此,您添加了加密图片不需要密码的约束 . 最后,因为非对称加密很慢,所以你需要使用AES来完成繁重的工作 .

这适用于RSA或任何其他非对称算法 .

Initial Run

首次运行时,生成密钥对并要求用户输入密码 .

将公钥存储为明文 . 使用密码生成的AES密钥加密私钥 .

Encryption

为每张图片生成不同的AES密钥,并使用它加密图像 . 使用公钥加密AES密钥并将其与图片一起存储 .

Decryption

让用户输入密码 . 从中生成第一个AES密钥 . 用它来解密私钥 . 使用私钥解密此图像的AES密钥 . 使用AES密钥解密文件并显示它 .

(我们实际上有4个密钥 . 我们需要密钥对来允许我们在没有密码的情况下加密 . 我们需要第一个AES密钥来安全地存储私钥 . 我们需要第二个和更改AES密钥来加密文件 . )

我认为这应该是安全的,除了密钥记录等攻击 . Java代码应该非常简单 . 希望这很清楚 .

================================================== ====================

完整示例使用AES和RSA . 对于Curve,仅切换RSA代码,虽然它不支持开箱即用,因此您需要一个外部库 . 此外,出于时间和简洁的考虑,代码的安全性应该低于应有的水平 . 例如,我使用的是ECB,而不是CBC .

package il.co.falk;

import javax.crypto.*;

import javax.crypto.spec.PBEKeySpec;

import javax.crypto.spec.SecretKeySpec;

import java.security.*;

import java.security.spec.KeySpec;

import java.security.spec.PKCS8EncodedKeySpec;

public class SecureFile {

private PublicKey publicKey;

private byte[] privateKeyArray;

private byte[] salt = {1,2,3,4,5,6,7,8};

public static void main(String[] args) {

String password = "PASSWORD";

SecureFile secureFile = new SecureFile(password);

secureFile.test();

}

public void test() {

String password = "PASSWORD";

String imageFile = "348756348975634897562398479623896";

ImageAndKey imageAndKey = encryptImage(imageFile.getBytes());

byte[] decryptedImage = decryptImage(imageAndKey, password);

System.out.println(new String(imageFile));

System.out.println(new String(decryptedImage));

}

public SecureFile(String password) {

try {

generateRSAKeys(password);

} catch (Exception e) {

e.printStackTrace();

}

}

public ImageAndKey encryptImage(byte[] imageBytes) {

try {

byte[] secretKeyBytes = generateAESKey();

byte[] encryptedFile = aesEncrypt(imageBytes, secretKeyBytes);

byte[] encryptedKey = rsaEncrypt(secretKeyBytes);

return new ImageAndKey(encryptedFile, encryptedKey);

} catch (Exception e) {

e.printStackTrace();

return null;

}

}

public byte[] decryptImage(ImageAndKey imageAndKey, String password) {

try {

byte[] secretKeyBytes = generateAESKey(password);

byte[] decryptedPrivateKey = aesDecrypt(privateKeyArray, secretKeyBytes);

byte[] decryptedKey = rsaDecrypt(imageAndKey.aesKey, decryptedPrivateKey);

SecretKey secretKey = new SecretKeySpec(decryptedKey, "AES");

secretKeyBytes = secretKey.getEncoded();

byte[] decryptedBytes = aesDecrypt(imageAndKey.imageBytes, secretKeyBytes);

return decryptedBytes;

} catch (Exception e) {

e.printStackTrace();

}

return null;

}

// RSA

private void generateRSAKeys(String password) throws Exception {

final KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");

keyGen.initialize(512); // TODO: make this 2048 at least

final KeyPair keyPair = keyGen.generateKeyPair();

publicKey = keyPair.getPublic();

PrivateKey privateKey = keyPair.getPrivate();

byte[] secretKeyBytes = generateAESKey(password);

byte[] privateKeyBytes = privateKey.getEncoded();

privateKeyArray = aesEncrypt(privateKeyBytes, secretKeyBytes);

}

public byte[] rsaEncrypt(byte[] plainText) throws Exception {

final Cipher cipher = Cipher.getInstance("RSA");

cipher.init(Cipher.ENCRYPT_MODE, publicKey);

byte[] cipherText = cipher.doFinal(plainText);

return cipherText;

}

public byte[] rsaDecrypt(byte[] cipherText, byte[] decryptedPrivateKeyArray) throws Exception {

PrivateKey privateKey = KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decryptedPrivateKeyArray));

final Cipher cipher = Cipher.getInstance("RSA");

cipher.init(Cipher.DECRYPT_MODE, privateKey);

byte[] plainText = cipher.doFinal(cipherText);

return plainText;

}

// AES

private byte[] aesEncrypt(byte[] plainText, byte[] secretKeyBytes) throws Exception {

Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");

cipher.init(Cipher.ENCRYPT_MODE, getSecretKey(secretKeyBytes));

byte[] cipherText = cipher.doFinal(plainText);

return cipherText;

}

public byte[] aesDecrypt(byte[] cipherText, byte[] secretKeyBytes) throws Exception {

Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");

cipher.init(Cipher.DECRYPT_MODE, getSecretKey(secretKeyBytes));

byte[] plainText = cipher.doFinal(cipherText);

return plainText;

}

private byte[] generateAESKey() throws Exception {

KeyGenerator keyGen = KeyGenerator.getInstance("AES");

keyGen.init(256);

SecretKey secretKey = keyGen.generateKey();

return secretKey.getEncoded();

}

private byte[] generateAESKey(String password) throws Exception {

SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");

KeySpec spec = new PBEKeySpec(password.toCharArray(), salt, 65536, 256);

SecretKey tmp = factory.generateSecret(spec);

SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES");

return secret.getEncoded();

}

private SecretKey getSecretKey(byte[] secretKeyBytes) throws Exception {

SecretKey secretKey = new SecretKeySpec(secretKeyBytes, "AES");

return secretKey;

}

// Classes

class ImageAndKey {

public byte[] imageBytes;

public byte[] aesKey;

public ImageAndKey(byte[] imageBytes, byte[] aesKey) {

this.imageBytes = imageBytes;

this.aesKey = aesKey;

}

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ECC(Elliptic Curve Cryptography)是一种基于椭圆曲线的加密算法,它在保证安全性的同时,具有较小的密钥长度和较高的加密效率。以下是ECC加密算法的Java实现。 1. 生成公私钥对 首先我们需要生成一对公私钥。在ECC算法,公钥由椭圆曲线上的一个点和曲线参数确定,私钥由一个随机数生成。下面是生成公私钥对的代码: ``` import java.security.*; import java.security.spec.*; import javax.crypto.*; import javax.crypto.spec.*; public class ECCKeyGenerator { public static void main(String[] args) throws Exception { // 选择椭圆曲线参数(secp256r1) String curveName = "secp256r1"; ECGenParameterSpec ecSpec = new ECGenParameterSpec(curveName); // 生成密钥对 KeyPairGenerator keyGen = KeyPairGenerator.getInstance("EC"); keyGen.initialize(ecSpec, new SecureRandom()); KeyPair keyPair = keyGen.generateKeyPair(); // 输出公钥和私钥 PrivateKey privateKey = keyPair.getPrivate(); PublicKey publicKey = keyPair.getPublic(); System.out.println("Private key: " + privateKey.toString()); System.out.println("Public key: " + publicKey.toString()); } } ``` 2. 加密解密 有了公私钥对,我们就可以使用ECC算法进行加密解密了。下面是加密解密的代码: ``` import java.security.*; import java.security.spec.*; import javax.crypto.*; import javax.crypto.spec.*; public class ECCEncryptDecrypt { public static void main(String[] args) throws Exception { // 选择椭圆曲线参数(secp256r1) String curveName = "secp256r1"; ECGenParameterSpec ecSpec = new ECGenParameterSpec(curveName); // 生成密钥对 KeyPairGenerator keyGen = KeyPairGenerator.getInstance("EC"); keyGen.initialize(ecSpec, new SecureRandom()); KeyPair keyPair = keyGen.generateKeyPair(); // 获取公私钥 PrivateKey privateKey = keyPair.getPrivate(); PublicKey publicKey = keyPair.getPublic(); // 明文 String plaintext = "Hello, world!"; // 加密 Cipher cipher = Cipher.getInstance("ECIES"); cipher.init(Cipher.ENCRYPT_MODE, publicKey); byte[] ciphertext = cipher.doFinal(plaintext.getBytes("UTF-8")); System.out.println("Ciphertext: " + new String(ciphertext, "UTF-8")); // 解密 cipher.init(Cipher.DECRYPT_MODE, privateKey); byte[] decrypted = cipher.doFinal(ciphertext); System.out.println("Decrypted: " + new String(decrypted, "UTF-8")); } } ``` 在加密过程,我们使用公钥对明文进行加密,得到密文;在解密过程,我们使用私钥对密文进行解密,得到原始明文。值得注意的是,ECC算法的加密解密速度较快,但是它需要进行大量的乘法和点加运算,因此在实现过程需要选择合适的椭圆曲线参数,以便在保证安全性的同时提高加密效率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值