java中long to String(和back)的简单对称加密

时间:2009-09-10 07:17:10

标签: java encryption hash

我正在寻找一种简单的方法将long转换为String并以一种“隐藏”long值的方式返回。

我宁愿避免在项目中为此功能添加另一个.jar。

它不一定是难以破​​解的加密,只是为了随机地看一下没有经验的眼睛。

增加:

我的目的是将一个计数器值(long类型)附加到URL作为跟踪参数,而不会让用户知道计数器的值(有点像tinyURL的哈希值),这样servlet就会知道计数器的值点击URL时。

由于

6 个答案:

答案 0 :(得分:8)

如果

X * Y = 1 (mod 2^32)

然后

A * (X * Y) = A (mod 2^32)
(A * X) * Y = A (mod 2^32)

因此,您可以通过将某个32位数乘以X来“加密”某个32位数,然后通过乘以Y来“解密”。您只需找到一些满足条件的非平凡X和Y.

例如,(X,Y)=(3766475841,1614427073)或(699185821,3766459317)。我刚刚用一个简单的蛮力程序找到了这些。

一旦你有了A * X,就可以使用Base-64或十六进制或URL中的某些类似方案对其进行编码。我建议使用Base64,因为它占用的空间更少,看起来相当“随机”。

答案 1 :(得分:2)

如果你只是模糊不清,那就像

那样微不足道

长 - > string - > char数组 对于每个字符,XOR与前一个输出值(在第一个字符之前有一些任意值) char数组 - >串

要显示每个字符,使用先前混淆的输入值进行异或(在第一个字符之前有一些任意值)

答案 2 :(得分:1)

嗯...没有进一步的细节,很难找到解决方案。你可以做很多不同的事情来实现你的目标......我想。

您可以使用随机数对其进行异或并存储这两个数字。当您的算法处于开放状态时(例如,如果您想将其置于开源中),这显然不起作用。

或者你可以使用一些对称加密算法,例如Twofish或蛇。

如果数字存储在客户端系统上并由客户端应用程序评估,则所有这些都是徒劳的。一旦分发应用程序,客户端就可以访问它存储的所有内容。如果信息是值得的,解密程序将在您的应用程序发布后立即可用。如果它不值得,那为什么要打扰?

答案 3 :(得分:1)

我喜欢使用Long.toString(value,36)。这将打印基础36中的数字,这是紧凑的,虽然神秘(如果数字> = 10)你可以使用Long.parseLong解析它(文本,36)

答案 4 :(得分:0)

带有one-time pad(OTP)的XOR提供了完美的保密性。我用OTP编写了一个加密整数的密码。我只是改编它以满足您的要求。它将一个long加密成一个带有前置盐的24个字符串六角形字符串,

-3675525778535888036 => 4fe555ca33021738a3797ab2
-6689673470125604264 => 76092fda5cd67e93b18b4f2f
 8956473951386520443 => 0fb25e533be315bdb6356a2a
 4899819575233977659 => 7cf17d74d6a2968370fbe149

这是代码,

public class IntegerCipher {
    // This is for salt so secure random is not needed
    private static Random PRNG = new Random();
    private String secret;

    public IntegerCipher(String secret) {
        if (secret.length() < 4)
            throw new IllegalArgumentException("Secret is too short");
        this.secret = secret;
    }

    public String encrypt(long value) {
        int salt = PRNG.nextInt();
        long otp = generatePad(salt);
        long cipher = value ^ otp;
        return String.format("%08x%016x", salt, cipher);
    }

    public long decrypt(String ciphertext) {
        if (ciphertext.length() != 24)
            throw new IllegalArgumentException("Invalid cipher text");
        try {
            int salt = (int) Long.parseLong(ciphertext.substring(0, 8), 16);
            long cipher = Long.parseLong(ciphertext.substring(8, 16), 16) << 32
                    | Long.parseLong(ciphertext.substring(16), 16);
            long otp = generatePad(salt);
            return cipher ^ otp;
        } catch (NumberFormatException e) {
            throw new IllegalArgumentException("Invalid hex value: "
                    + e.getMessage());
        }
    }

    private long generatePad(int salt) {
        String saltString = Integer.toString(salt);
        String lpad = saltString + secret;
        String rpad = secret + saltString;
        return ((long) lpad.hashCode()) << 32 | (long) rpad.hashCode();
    }

    public static void main(String[] args) {
        IntegerCipher cipher = new IntegerCipher("Top Secret");
        Random rand = new Random();
        for (int i = 0; i < 100; i++) {
            Long n = rand.nextLong();
            String ciphertext = cipher.encrypt(n);
            Long m = cipher.decrypt(ciphertext);
            System.out.printf("%24d => %s\n", n,  ciphertext);
            assert(m == n);
        }
    }
}

答案 5 :(得分:0)

要以确定的方式加密短明文,您可能需要查看 FFSEM