2016-03-01 229 views
0

我想用我的publicKey加密一個secretKey,然後用私鑰將其解密到別的地方。我可以很好地加密和解密,但是當我這樣做時,我得到了一個完全不同的密鑰。用RSA公鑰和私鑰加密和解密一個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提供商創建的公共代碼/私有密鑰對,雖然我沒有得到任何不同的結果,當我DiffieHellman跑離了SunJCE或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 ==

回答

2

你首先應該知道你正在嘗試做之前做:

  • 沒有填充的RSA是完全不安全的;
  • 您使用密碼基密碼進行密碼驗證,只有密碼纔有意義;
  • 你拿出一個DES密鑰,它又是完全不安全的;
  • 你可能用一個隨機的鹽生成它,所以輸出是隨機的。

整個協議沒有意義。你試圖直接用DH(一種執行密鑰協議的方案)進行加密表明你還沒有研究足夠的密碼。

加密技術並不是要讓事情發揮作用。這是關於讓事情安全。你不能僅僅嘗試一下就做到這一點。至少學習密碼學的基礎知識,然後編碼

+0

我使用了PBE的密碼,而不是上面建議的密鑰。我從來沒有拿出DES密鑰,所以我不確定你在哪裏看到這個。另外,我沒有按照你的建議對DH進行加密/解密,儘管我試圖從這個算法中得到一個工作密鑰。該代碼完全顯示了我正在嘗試的內容。我相信這些都是基本概念。 – SteveManC

+0

您正在使用「PBEWithMD5AndDES」... –

+0

我的錯誤。謝謝 – SteveManC

0

問題實際上是我存儲/檢索我的密鑰的方式。我曾經使用私人密鑰存儲和公共文件。我檢索這些密鑰的方式導致它們變得格格不入,因此我的密碼失敗,需要使用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; 
}