首先,我不是Java程序员。我正在寻找这个问题的示例解决方案,因为我所拥有的Java开发人员在加密方面的经验不多。我们在网上发现的一切都与加密网页和处理MS密钥库有关。我们只想使用来自PowerBuilder (PB)的单个字符串,并能够在Java中解密它。这里的限制是MS库。由于某些限制,我们只能使用这种加密方法,所以应该由Java端来处理抛出的内容。
我所拥有的是一个PB版本10.2程序,它需要调用这个Java实用程序并传递给它一个用户名和密码。我们正试图将密码加密为命令行友好字符串,因为PB就是这样对Java应用程序进行调用的。
在PB中,我使用以下对象:http://www.topwizprogramming.com/freecode_crypto.html
代码所做的,是包装在advapi32.dll中找到的Microsoft加密API。它使用的功能如下:
CryptAcquireContext http://msdn.microsoft.com/en-us/library/aa379886(VS.85).aspx
CryptCreateHash http://msdn.microsoft.com/en-us/library/aa379908(VS.85).aspx
CryptHashData http://msdn.microsoft.com/en-us/library/aa380202(VS.85).aspx
CryptDeriveKey http://msdn.microsoft.com/en-us/library/aa379916(VS.85).aspx
CryptEncrypt http://msdn.microsoft.com/en-us/library/aa379924(VS.85).aspx
它使用的是微软强大的密码提供者和PROV_RSA_FULL。代码获取要加密的数据,将其转换为BLOB,然后BLOB传递给加密函数。在那里,它启动上下文,从上下文创建哈希对象,散列密码,从哈希获取会话密钥,然后调用加密/解密。最后一件事是,它将返回的BLOB转换为ANSI字符集下的字符串。
有一些常量我一眼就能理解,有些是从哪里来的,另一些则不是这样:常数字符串KEY_CONTAINER = "MyKeyContainer“常数ULong PROV_RSA_FULL =1 ULong CALG_MD5 =1常数ULong CALG_MD5= 32771常数ULong CALG_RC4 = 26625常数ULong ENCRYPT_ALGORITHM = CALG_RC4常数ULong CRYPT_NEWKEYSET =8常数ULong ERROR_MORE_DATA =2 34
不管这是在1.5中完成的,使用的是像BouncyCastle这样的工具,还是使用带有Sun密码接口的Sun密码接口,我不在乎,我们只是渴望看到这一工作,并且诚实地超越了我们的头脑。
嘿,我需要加密一个字符串并存储一个文件,然后我需要再次读取该文件,并将相同的字符串解密回来。但我不想把整个文件都加密。一旦在文件中存储了所需的加密值,就需要单独将其转换为原始字符串。你能帮我拿出样本代码吗。
发布于 2009-03-18 18:10:39
import java.security.GeneralSecurityException;
import java.security.MessageDigest;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
public class Decrypt
{
public static void main(String... argv)
throws Exception
{
byte[] password = "password".getBytes("UTF-8");
byte[] ciphertext = { -68, -112, 66, 78, 85, 50, 22, -63,
16, 24, -45, 4, -116, -14, 88, 34,
-85, 116, 105, 59, 45, -126 };
byte[] plaintext = decrypt(password, ciphertext);
System.out.println(new String(plaintext, "UTF-8"));
}
public static byte[] decrypt(byte[] password, byte[] ciphertext)
throws GeneralSecurityException
{
MessageDigest digest = MessageDigest.getInstance("MD5");
byte[] hash = digest.digest(password);
Cipher rc4 = Cipher.getInstance("RC4");
rc4.init(Cipher.DECRYPT_MODE, new SecretKeySpec(hash, "RC4"));
return rc4.doFinal(ciphertext);
}
}注:
这种“加密”太可怕了。RC4是一种密钥流密码。永远不会对多条消息使用相同的密钥!以这种方式对多条消息使用相同的密码,这使得恢复纯文本和给定多个密码文本的密钥变得非常简单。考虑到MD5的弱点,他们可能也可以恢复密码。这些缺陷足以破坏一个好的流密码,但是RC4和MD5一样也有自己的漏洞,不推荐用于新的应用程序。
我相信您知道所有这些,并且受到一些遗留应用程序的限制,但是如果其他人看到了这个答案,他们需要理解您被迫使用的PowerBuilder“加密”库是不合格的实现。
由于密码输入和输出始终是“二进制”,所以通常使用文本编码,例如Bas-64或Bas-85,当密码文本必须通过面向文本的通道(如命令行)时。如果可能的话,在调用Java实用程序之前,Bas-64可以对密码文本进行编码吗?这将使您免受任何字符编码问题的影响。
https://stackoverflow.com/questions/658826
复制相似问题