2010-07-06 235 views
9

我对加密很陌生。Java加密与硬编码密钥交替使用

我已经看了看javax.crypto中的文档,并得到了文件中使用此代码工作的加密...

File saveFile = new File("Settings.set"); 
     saveFile.delete(); 
     FileOutputStream fout = new FileOutputStream(saveFile); 

     //Encrypt the settings 
     //Generate a key 
     byte key[] = "My Encryption Key98".getBytes(); 
     DESKeySpec desKeySpec = new DESKeySpec(key); 
     SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); 
     SecretKey skey = keyFactory.generateSecret(desKeySpec); 

     //Prepare the encrypter 
     Cipher ecipher = Cipher.getInstance("DES"); 
     ecipher.init(Cipher.ENCRYPT_MODE, skey); 
     // Seal (encrypt) the object 
     SealedObject so = new SealedObject(this, ecipher); 

     ObjectOutputStream o = new ObjectOutputStream(fout); 
     o.writeObject(so); 
     o.close(); 

但是如果你是一个聪明的黑客(或者也许因为我想通这甚至业余),你所要做的就是打开包含此代码的类文件,并且加密密钥(My Encryption Key98)清晰可见。

你如何加密加密密钥? ......大声笑...你能吗?

感谢您的帮助!

+0

作为一个侧面说明,你可能需要重新设计你的'密码。 getInstance(“DES”)方法调用:http://stackoverflow.com/questions/3180878/exception-in-aes-decryption-algorithm-in-java/3181250#3181250 – 2010-07-06 16:37:36

回答

6

如果攻击者能够访问软件和文件两种,它可以解密。有一些方法可以解决这个问题:

  • 使用非对称密钥。用公钥加密文件,只能用私钥解密。这假定软件不需要解密文件。
  • 使用Diffie-Hellman交换。如果你想通过网络发送加密的数据,双方都可以建立一个密钥,而不需要攻击者知道它。

如果程序需要同时对数据进行加密和解密,那么您就无能为力。攻击者可以简单地运行该程序并查看解密的信息。

0

我不认为这是可能的,而无需输入加密和解密密钥的用户。

您可以采用一些技术来使它更难查看没有完整的源代码的关键,但它不会是安全的。

+0

感谢您的帮助! – DRJTower 2010-07-06 17:03:20

0

如果你的程序可以加密/解密本身就是一个文件,那么你需要执行解密的每件事都已经内置到程序,所以确定肇事者可以解密你加密的文件。

如果可能的话,要求用户提供一个“密码”,并使用他们给你的加密/解密密钥。

0

用户无法看到自己的加密密钥很重要吗?或者仅仅重要的是,通过发现他赢得的钥匙,用户不应该从而知道其他人的钥匙?

你可以提示用户输入个人密钥,或者其存储在外部或每次你需要它的时候提示用户。这样每个用户的密钥将是他自己的,并且不可用于解密由其他机器上的其他用户存储的文档。

3

攻击者总是可以做的一切程序可以做的,平时多了不少。使事情安全的唯一方法是不受程序控制的使用信息。请求用户在操作系统的控制下输入密码或将信息放入商店。如果攻击者拥有物理访问权或甚至许多权利,则后者将无济于事,除非涉及特殊硬件(如可信平台模块(TPM))。

1

那么,如果该程序可以解密,而无需用户额外的输入数据,你真的不能避免有人访问该文件,如果他有进入其他程序。

如果您只针对Windows,则可能需要查看Data Protection API (DPAPI)。它基本上做同样的事情,但用于加密的密码是由用户(或机器)作用域上的操作系统保护的。简而言之:您需要用户登录(或在给定用户帐户上运行的程序)才能访问密钥(或者机器范围内的任何用户在机器上登录)。

我不知道如何从Java访问API,但Google带来了一些包装库。

1

不要硬编码密钥。假设您没有用户输入密码,请将您的代码配置为从普通文件中提取加密密钥,然后依靠操作系统安全性来保证文件安全。当系统管理员认为有必要时提供迁移到新密钥的方法。

0

最安全的方法是不使用任何加密,只要把你的user.properties你的home目录,用下面的代码:

String userhome = System.getProperty("user.home"); 
String username = system.getProperty("user.name"); 
String hostname = java.net.InetAddress.getLocalHost().getHostName(); 

if (hostname.equals("webserver") && username.equals("root")){ 
ResourceBundle user = ResourceBundle.getBundle(userhome/ "user.properties"); 
}