簡體   English   中英

使用RSA公鑰和私鑰對SecretKey進行加密和解密

[英]Encrypt and decrypt a SecretKey with RSA public and private keys

我正在嘗試使用我的publicKey加密secretKey,然后使用私鑰將其解密。 我可以很好地加密和解密,但是當我這樣做時,我會得到一個完全不同的密鑰。

這是創建公鑰/私鑰對的代碼

public static KeyPair generateKeyPair()
{
    KeyPair returnPair = null;
    try
    {
        KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", "SunJSSE");

        System.out.println("provider:" + kpg.getProvider().getName());

        SecureRandom random = SecureRandom.getInstance("SHA1PRNG");

        kpg.initialize(1024, random);

        returnPair = kpg.generateKeyPair();

    }catch(Exception e)
    {
        e.printStackTrace();
    }
    return returnPair;
}

我指定了SunJSSE提供程序,盡管與從SunJCE的DiffieHellman或RSA / SunRSASign提供程序運行時得到的結果沒有什么不同。 我對Java安全性是陌生的,因此這些概念仍然有些難為情。

這是我用來生成密鑰的代碼

    public static SecretKey generateSecretKey(String keyPassword)
{
    SecretKey key = null;
    try
    {
        SecretKeyFactory method = SecretKeyFactory.getInstance("PBEWithMD5AndDES");

        //System.out.println("salt length: " + new SaltIVManager().getSalt().length);

        PBEKeySpec spec = new PBEKeySpec(keyPassword.toCharArray(), new SaltIVManager().getSalt(), 10000, 128);

        key = method.generateSecret(spec);

        System.out.println("generate secret key length: " + key.getEncoded().length); 

    }catch(Exception e)
    {
        e.printStackTrace();
    }
    return key;
}

這是我用來加密/解密我的密鑰的兩種方法

    public static byte[] encryptSecretKey(SecretKey secretKey, PublicKey publicKey)
{
    byte[] encryptedSecret = null;
    try
    {

        Cipher cipher = Cipher.getInstance("RSA/ECB/NOPADDING");

        System.out.println("provider: " + cipher.getProvider().getName());

        cipher.init(Cipher.ENCRYPT_MODE, publicKey);

        System.out.println("original secret key: " + Base64.getEncoder().encodeToString(secretKey.getEncoded()) + " \n secretkey encoded length: " + secretKey.getEncoded().length);

        encryptedSecret = cipher.doFinal(secretKey.getEncoded());


        System.out.println("encrypted secret: " + Base64.getEncoder().encodeToString(encryptedSecret)); 

    }catch(Exception e)
    {
        e.printStackTrace();
    }
    return encryptedSecret;
}



public static SecretKey decryptSecretKey(byte[] encryptedKey, PrivateKey privateKey)
{
    SecretKey returnKey = null;
    try
    {
        Cipher cipher = Cipher.getInstance("RSA/ECB/NOPADDING");

        System.out.println("provider: " + cipher.getProvider().getName());

        cipher.init(Cipher.DECRYPT_MODE, privateKey);

        System.out.println("encryptedkey length: " + encryptedKey.length);

        byte [] encodedSecret = cipher.doFinal(encryptedKey);

        System.out.println("encoded Secret after decrypt: " + Base64.getEncoder().encodeToString(encodedSecret));

        returnKey = new SecretKeySpec(encodedSecret, 0, encodedSecret.length, "PBEWithMD5AndDES");

        System.out.println("secret key: " + Base64.getEncoder().encodeToString(returnKey.getEncoded()));

        System.out.println("secret key length post decrypt: " + returnKey.getEncoded().length);
    }catch(Exception e)
    {
        e.printStackTrace();
    }
    return returnKey;
}

RSA算法是我唯一使用密鑰的算法。 如果我指定DiffieHellman alg。 對於密鑰對,我根本無法加密/解密。 如果有人對我做錯了什么有任何見識,任何幫助將不勝感激。 當我以當前狀態調用此密鑰時,我以此值的密鑰= cGFzczEyMw ==開頭,並在加密/解密后以此值的密鑰結束

SvMNufKu2JA4hnNEwuWdOgJu6FxnNmuLYzxENhTsGgFzc / i3kQIXbeVaJUkJck918BLCnm2u2QZCyVvJjYFXMLBFga0Zq0WMxSbIZvPz1J / EDi9dpsAkbFhLyBWmdDyPr + w7DMDsqHwKuA8y / IRKVINWXVrp3Hbt8goFZ0nGIlKVzMdJbGhNi3HZSAw4R6fXZNKOJ3nN6wDldzYerEaz2MhJqnZ3Dz4psA6gskomhjp / G0yhsGO8pllMcgD0jzhL86RGrBhjj04Bj0ps3AAACkQLcCwisso8dWigvR8NX9dnI0C / gc6FqmNenWI1 / AoPgmcRyFdlO7A2i9JXoSj + YQ ==

首先,您應該先知道自己要做什么:

  • 沒有填充的RSA是完全不安全的;
  • 您使用密鑰進行基於密碼的加密,只有在-好-密碼的情況下才有意義;
  • 您拿出DES密鑰,這又是完全不安全的;
  • 您可能使用隨機生成的鹽生成了它,因此輸出是隨機的。

整個協議沒有意義。 您嘗試直接使用DH(執行密鑰協商的方案)進行加密的過程表明您對加密技術的研究還不夠深入。

使用密碼學並不是要使事情正常進行。 這是為了確保事情安全 您不能僅僅通過嘗試來做到這一點。 至少學習密碼學的基礎知識然后進行編碼

實際上,問題在於我存儲/檢索密鑰的方式。 我曾為私人使用密鑰庫,而為公眾使用文件。 我檢索這些密鑰的方式導致它們變得格式錯誤,從而導致密碼失敗以及需要使用NOPADDING來獲取任何形式的輸出。 這是我用於RSA密鑰的新存儲代碼-將它們寫入文件。

    public static boolean saveKeys(Key privateKey, Key publicKey, char[] password, String alias)
{
    boolean saved = false;
    try
    {
        KeyPair kp = generateKeyPair();


        KeyFactory kf = KeyFactory.getInstance("RSA");

        if(privateKey != null)
        {

            File privKeyFile = new File(System.getProperty("user.home") + "/.etc/privkey");

            if(!privKeyFile.exists())
            {
                privKeyFile.createNewFile();
            }

            System.out.println("private key: " + Base64.getEncoder().encodeToString(kp.getPrivate().getEncoded()));

            RSAPrivateKeySpec pubSpec = kf.getKeySpec(kp.getPrivate(), RSAPrivateKeySpec.class);

            ObjectOutputStream oout = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(System.getProperty("user.home") + "/.etc/privkey")));

            oout.writeObject(pubSpec.getModulus());

            oout.writeObject(pubSpec.getPrivateExponent());

            oout.close();


        }if(publicKey != null)
        {

            File pubKeyFile = new File(System.getProperty("user.home") + "/.etc/pubkey.pub");

            if(!pubKeyFile.exists())
            {
                pubKeyFile.createNewFile();
            }

            System.out.println("public key: " + Base64.getEncoder().encodeToString(kp.getPublic().getEncoded()));

            RSAPublicKeySpec pubSpec = kf.getKeySpec(kp.getPublic(), RSAPublicKeySpec.class);

            ObjectOutputStream oout = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(System.getProperty("user.home") + "/.etc/pubkey.pub")));

            oout.writeObject(pubSpec.getModulus());

            oout.writeObject(pubSpec.getPublicExponent());

            oout.close();

        }



    }catch(Exception e)
    {
        e.printStackTrace();
    }
    return saved;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM