Last active
September 27, 2024 10:33
-
-
Save Ghost-chu/f4697d85352d6431fbc58398ba961405 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package com.ghostchu.peerbanhelper.downloader.impl.bitcomet.crypto; | |
| import org.bouncycastle.jce.provider.BouncyCastleProvider; | |
| import javax.crypto.Cipher; | |
| import javax.crypto.Mac; | |
| import javax.crypto.SecretKeyFactory; | |
| import javax.crypto.spec.PBEKeySpec; | |
| import javax.crypto.spec.SecretKeySpec; | |
| import java.io.ByteArrayOutputStream; | |
| import java.nio.charset.StandardCharsets; | |
| import java.security.SecureRandom; | |
| import java.security.Security; | |
| import java.util.Base64; | |
| public class BCAESTool { | |
| static { | |
| Security.addProvider(new BouncyCastleProvider()); | |
| } | |
| public static String credential(String json, String cid) throws Exception { | |
| // Ensure Bouncy Castle is added to your project for PBKDF2 | |
| byte[] t = new byte[8]; | |
| byte[] r = new byte[8]; | |
| SecureRandom random = new SecureRandom(); | |
| random.nextBytes(t); | |
| random.nextBytes(r); | |
| byte[] n = PBKDF2(cid.getBytes(StandardCharsets.UTF_8), t, 10000, 32, "SHA1"); | |
| byte[] i = PBKDF2(cid.getBytes(StandardCharsets.UTF_8), r, 10000, 32, "SHA1"); | |
| Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding"); | |
| SecretKeySpec keySpec = new SecretKeySpec(n, "AES"); | |
| cipher.init(Cipher.ENCRYPT_MODE, keySpec); | |
| byte[] s = cipher.doFinal(pad(json.getBytes(StandardCharsets.UTF_8), 16)); | |
| byte[] o = cipher.getIV(); | |
| ByteArrayOutputStream msg = new ByteArrayOutputStream(); | |
| msg.write(3); // m[0] | |
| msg.write(1); // m[1] | |
| msg.write(t); | |
| msg.write(r); | |
| msg.write(o); | |
| msg.write(s); | |
| Mac hmac = Mac.getInstance("HmacSHA256"); | |
| hmac.init(new SecretKeySpec(i, "HmacSHA256")); | |
| hmac.update(msg.toByteArray()); | |
| byte[] sig = hmac.doFinal(); | |
| msg.write(sig); | |
| // Use an HTTP client like OkHttp or Apache HttpClient for the POST request | |
| return Base64.getEncoder().encodeToString(msg.toByteArray()); | |
| } | |
| private static byte[] PBKDF2(byte[] password, byte[] salt, int iterations, int keyLength, String hashAlgorithm) throws Exception { | |
| PBEKeySpec spec = new PBEKeySpec(new String(password, StandardCharsets.UTF_8).toCharArray(), salt, iterations, keyLength * 8); | |
| SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmac" + hashAlgorithm); | |
| return factory.generateSecret(spec).getEncoded(); | |
| } | |
| private static byte[] pad(byte[] data, int blockSize) { | |
| int paddingRequired = blockSize - (data.length % blockSize); | |
| byte[] padded = new byte[data.length + paddingRequired]; | |
| System.arraycopy(data, 0, padded, 0, data.length); | |
| for (int i = data.length; i < padded.length; i++) { | |
| padded[i] = (byte) paddingRequired; | |
| } | |
| return padded; | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment