[我正在尝试通过C#为instagram网络认证生成类以生成base64字符串。作为我代码的基础,我使用了这个node.js示例-click它看起来很棒并且完美地工作,但是我不知道如何实现这种魔力:
const key = crypto.pseudoRandomBytes(32);
publicKey = '5a0b3cd9a12fef6c786afe28cfceef60550d27ea6657bb15be4a271eaadb0903';
const encryptedKey = tweetnacl.sealedbox.seal(key, Buffer.from(publicKey, 'hex'));
对于aes-256-gcm加密,我使用BouncyCastle库,但是找不到类似tweetnacl.sealedbox.seal
的操作据我了解,此操作返回的uint8array具有加密的publicKey
import nacl from 'tweetnacl';
import nonceGenerator from './nonce';
import {overheadLength} from './consts';
import {zero} from './utils';
export default function seal(m, pk){
var c = new Uint8Array(overheadLength + m.length);
//overheadLength = nacl.box.publicKeyLength + nacl.box.overheadLength;
var ek = nacl.box.keyPair();
c.set(ek.publicKey);
var nonce = nonceGenerator(ek.publicKey, pk);
var boxed = nacl.box(m, nonce, pk, ek.secretKey);
c.set(boxed, ek.publicKey.length);
zero(ek.secretKey);
return c;
};
我自己很难做,非常感谢您的帮助。
我尝试移植到c#,但是解密存在问题
private static encryptPassword(string password, string encryptionPubKey, string encryptionKeyId)
{
byte[] passwordAsByte = Encoding.ASCII.GetBytes(password);
byte[] data = Convert.FromBase64String(encryptionPubKey);
string decoededPubKey = Encoding.UTF8.GetString(data);
decoededPubKey = decoededPubKey.Replace("-----BEGIN PUBLIC KEY-----", "");
decoededPubKey = decoededPubKey.Replace("-----END PUBLIC KEY-----", "");
SecureRandom random = new SecureRandom();
byte[] randKey = new byte[32];
random.NextBytes(randKey);
byte[] iv = new byte[12];
random.NextBytes(iv);
//String date = String.valueOf(new Date().getTime() / 1000);
long tsLong = DateTimeOffset.UtcNow.ToUnixTimeSeconds() / 1000;
string date = tsLong.ToString();
var header = new MemoryStream(2);
header.Write(BitConverter.GetBytes(Convert.ToInt32(1)));
header.Write(BitConverter.GetBytes(Convert.ToInt32(int.Parse(encryptionKeyId))));
MemoryStream timeAAD = new MemoryStream(10);
timeAAD.Write(Encoding.ASCII.GetBytes(date));
//////////////////////////////////////////////////////////////////
X509EncodedKeySpec publicSpec = new X509EncodedKeySpec(Base64.decode(decoededPubKey, Base64.NO_WRAP));
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKey = keyFactory.generatePublic(publicSpec);
Cipher rsaCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
rsaCipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] rsaEncrypted = rsaCipher.doFinal(randKey);
MemoryStream sizeBuff = new MemoryStream(2);
sizeBuff.order(ByteOrder.LITTLE_ENDIAN);
sizeBuff.putChar((char) rsaEncrypted.Length);
///////////////////////////////////////////////////////////////////////
AeadParameters parameters = new AeadParameters(new KeyParameter(randKey), 128, iv, timeAAD.ToArray());
GcmBlockCipher gcmEngine = new GcmBlockCipher(new AesFastEngine());
gcmEngine.Init(true, parameters);
byte[] gcmText = new byte[gcmEngine.GetOutputSize(passwordAsByte.Length)];
int len = gcmEngine.ProcessBytes(passwordAsByte, 0, passwordAsByte.Length, gcmText, 0);
gcmEngine.DoFinal(gcmText, len);
byte[] encPass = Arrays.CopyOfRange(gcmText, 0, gcmText.Length - 16);
byte[] authTag = Arrays.CopyOfRange(gcmText, gcmText.Length - 16, gcmText.Length);
var a = header.Position + iv.Length + sizeBuff.Position + rsaEncrypted.Length + authTag.Length + encPass.Length;
MemoryStream result = new MemoryStream(a);
result.Write(header.ToArray());
result.Write(iv);
result.Write(sizeBuff.ToArray());
result.Write(rsaEncrypted);
result.Write(authTag);
result.Write(encPass);
//return new Pair(Convert.ToInt64(date), Base64.encodeToString(result.array(), Base64.NO_WRAP));
}
这几乎是准备就绪的代码,如果有更正,请在注释中写出,我会修复它