首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >需要使用Microsoft Crypto API在Java中使用示例解密字符串

需要使用Microsoft Crypto API在Java中使用示例解密字符串
EN

Stack Overflow用户
提问于 2009-03-18 15:40:19
回答 1查看 11.1K关注 0票数 0

首先,我不是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密码接口,我不在乎,我们只是渴望看到这一工作,并且诚实地超越了我们的头脑。

嘿,我需要加密一个字符串并存储一个文件,然后我需要再次读取该文件,并将相同的字符串解密回来。但我不想把整个文件都加密。一旦在文件中存储了所需的加密值,就需要单独将其转换为原始字符串。你能帮我拿出样本代码吗。

EN

回答 1

Stack Overflow用户

发布于 2009-03-18 18:10:39

代码语言:javascript
复制
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可以对密码文本进行编码吗?这将使您免受任何字符编码问题的影响。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/658826

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档