加密/解密Android和Java中不同值的字符串

加密/解密Android和Java中不同值的字符串,java,android,security,encryption,Java,Android,Security,Encryption,我用这段代码在Java和Android中加密和解密一些字符串,在每个系统中我得到不同的值 我使用的代码来自(我不会粘贴它,因为它相当大) 例如,在Android中加密“aa”时,我得到以下信息: 1C6BD31C57F42ACFD0EDD2DD5B7A92CA 我得到的字符串与Java中的seed键完全相同: 61FAD1203B7AC92AD9345771AA273DA5 有什么想法吗 提前谢谢 看起来每次加密时它都会有不同的输出。这是正常的。这只是我的猜测,但我认为原因是你的关键推导。但是我

我用这段代码在Java和Android中加密和解密一些字符串,在每个系统中我得到不同的值

我使用的代码来自(我不会粘贴它,因为它相当大)

例如,在Android中加密“aa”时,我得到以下信息: 1C6BD31C57F42ACFD0EDD2DD5B7A92CA

我得到的字符串与Java中的seed键完全相同: 61FAD1203B7AC92AD9345771AA273DA5

有什么想法吗


提前谢谢

看起来每次加密时它都会有不同的输出。这是正常的。

这只是我的猜测,但我认为原因是你的关键推导。但是我不是一个真正的Java开发人员,所以我可能没有正确理解代码

加密和解密时,此代码始终调用getRawKey()。getRawKey()看起来像是一个他们称之为种子或共享秘密的东西,并使用它来计算一个新的随机密钥来进行实际的加密/解密

SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
    sr.setSeed(seed);
    kgen.init(128, sr); // 192 and 256 bits may not be available
    SecretKey skey = kgen.generateKey();
根据Java docs found,setSeed()重新设定此随机对象的种子。给定的种子补充而不是替换现有种子


我的猜测是,RNG的初始状态在每个系统/平台上都是不同的,因此它会给出不同的结果。您应该将密钥派生修复为更标准和一致的,或者使用已经建立的加密系统,如Bouncy Castle库中的PGP

本例将演示如何加密和解密,为此,我们需要一个将一个字符转换为另一个字符的shif密钥,例如,如果您有“b”并使用shift key=2,则它将变成COM 98+2=100,这是='d',再次是100-2=98,这是'b',因此将以这种方式执行

让你的字符串在这里加密

final int shift_key = 4; //it is the shift key to move charcter, like if i have 'a' then a=97+4=101 which =e and thus it changes
    String plainText = "piran jhandukhel"; 
    char character; 
     char ch[]=new char[plainText.length()];//for storing encrypt char
   for (int iteration = 0; iteration < plainText.length(); iteration++)
            {
                    character = plainText.charAt(iteration); //get characters
                    character = (char) (character + shift_key); //perform shift
              }     ch[iteration]=character;//assign char to char array
     String encryptstr = String.valueOf(ch);//converting char array to string
     Toast.makeText(this, "Encrypt string is "+ encryptstr Toast.LENGTH_LONG).show();
   for(int i=0;i<encryptstr.length();i++)
     {
        character=str.charAt(i);
        character = (char) (character -shift_key); //perform shift
            ch[i]=character;
     }
 Stirng decryptstr = String.valueOf(ch);
     Toast.makeText(this, "Decrypted String is "+decryptstr, Toast.LENGTH_LONG).show();
final int shift_key=4//它是移动字符的shift键,比如如果我有“a”,那么a=97+4=101,后者=e,因此它会改变
字符串明文=“piran jhandukhel”;
字符;
char ch[]=新字符[plainText.length()]//用于存储加密字符
for(int iteration=0;iteration
让你的字符串在这里解密

final int shift_key = 4; //it is the shift key to move charcter, like if i have 'a' then a=97+4=101 which =e and thus it changes
    String plainText = "piran jhandukhel"; 
    char character; 
     char ch[]=new char[plainText.length()];//for storing encrypt char
   for (int iteration = 0; iteration < plainText.length(); iteration++)
            {
                    character = plainText.charAt(iteration); //get characters
                    character = (char) (character + shift_key); //perform shift
              }     ch[iteration]=character;//assign char to char array
     String encryptstr = String.valueOf(ch);//converting char array to string
     Toast.makeText(this, "Encrypt string is "+ encryptstr Toast.LENGTH_LONG).show();
   for(int i=0;i<encryptstr.length();i++)
     {
        character=str.charAt(i);
        character = (char) (character -shift_key); //perform shift
            ch[i]=character;
     }
 Stirng decryptstr = String.valueOf(ch);
     Toast.makeText(this, "Decrypted String is "+decryptstr, Toast.LENGTH_LONG).show();

for(int i=0;i如果您再试一次,您会得到相同的加密字符串吗?我本以为不会…通常会有一个随机组件,但您仍然可以对其进行解密。桌面和android java版本之间是否存在编码差异,其中“aa”不代表相同的十六进制?此代码段不好;不要使用它。这是错误的“密钥派生”不可靠或不安全。请改用PBKDF2。您可以看到问题是我无法解密,我得到了一个关于错误填充的异常。(我将检查@erickson)@erickson我正在尝试在Android上实现您所指的答案。但是,我在以下行初始化cipher对象时出错:cipher.init(cipher.ENCRYPT_MODE,secret);错误为:(InvalidKeyException:仅支持SecretKey)。我认为你在Java中所做的不能直接移植到Android。我在纯Java应用程序中实现了你的代码,并设法使其正常工作。只有当它是一种使用IV(如CBC或CTR)的模式时,这才是正确的。这似乎是直接的ECB,意味着相同的明文在相同的密钥下加密到相同的密文。我认为早期版本的Android错误地将种子作为RNG的起点,这在后来的版本中得到了纠正,这意味着已经损坏的代码现在不再运行,不幸的是,这个蹩脚的例子已经吸引了至少10多个程序员进入同一个洞。这个答案是正确的。此外,底层的implemPRNG的加密不保证平台间的一致性(因此Android设备上的PRNG不一定会以与另一平台上相同的种子给出相同的结果)。如果您希望这一点起作用,请使用更好的方法替换密钥派生,例如运行良好的基于密码的加密(PBE)获取密码并形成密钥的算法(bcrypt和PBKDF2是两个好的算法)。实际上,这在ICS中没有得到纠正。Android的SHA1PRNG
SecureRandom
的行为与Java SE不同:如果在
getBytes()之前调用
setSeed()
,种子将用于设置PRNG。在Java SE上,它是从
/dev/random
等自动种子,并且
setSeed()
添加了种子。因此,(断开的)代码仍然可以在Android上工作,但如果您想要一些互操作性,请使用PBE。从来没有任何保证PRNG在不同平台上工作相同(甚至跨设备)。如果您在Windows主机上运行一个使用SecureRandom的Java程序,在Unix主机上运行一个使用SecureRandom的Java程序,您会得到不同的结果,因为随机数来自不同的位置。Android也是如此。课程非常基本->不要假设您可以从软件角度了解PRNG的工作方式,不要依赖于此实现互操作性…您应该这样做“我也不在乎这个抽象层次。我认为这是一个笑话,因为这个应用程序有点小问题。@kroot是的,但在低层次上,有些人仍然使用它,例如,如果你去苹果iphone市场,那么有许多应用程序是基于Caesar密码的。”。