Saving/Reading BigInteger RSA keys to/from file - rsa

I am trying to implement RSA using Big integers i can currently encrypt and decrypt fine but I need to be able to take the 2 lots of 2 BigIntegers n, e and n, d of any Bit length up to 2048 and then some how save them to files named publicKey.txt and privateKey.txt . and then be able to read it in later. does anyone have any ideas for this.
would like to somehow save them like this so i can separate them into their 2 parts on reading them in using the , as the separator
publicKey.txt
n,e
privateKey.txt
n,d

RSA standard defines ASN.1 encoding for serializing private and public keys for transferring and storage. This format is a standard for cryptography software.

Related

Why does Blockcypher signer tool return some extra characters than bip32 dart package?

I'm trying to sign a transaction skeleton Blockcypher returns, in order to send it along, following https://www.blockcypher.com/dev/bitcoin/#creating-transactions.
For this example, I'll use the completely-unsafe 'raw raw raw raw raw raw raw raw raw raw raw raw' mnemonic, which using dart bip32 package creates a BIP32 with private key 0x05a2716a8eb37eb2aaa72594573165349498aa6ca20c71346fb15d82c0cbbf7c and address mpQfiFFq7SHvzS9ebxMRGVohwHTRJJf9ra for BTC testnet.
Blockcypher Tx Skeleton tosign is 1cbbb4d229dcafe6dc3363daab8de99d6d38b043ce62b7129a8236e40053383e.
Using Blockcypher signer tool:
$ ./signer 1cbbb4d229dcafe6dc3363daab8de99d6d38b043ce62b7129a8236e40053383e 05a2716a8eb37eb2aaa72594573165349498aa6ca20c71346fb15d82c0cbbf7c
304402202711792b72547d2a1730a319bd219854f0892451b8bc2ab8c17ec0c6cba4ecc4022058f675ca0af3db455913e59dadc7c5e0bd0bf1b8ef8c13e830a627a18ac375ab
On the other hand, using bip32 I get:
String toSign = txSkel['tosign'][0];
var uToSign = crypto.hexToBytes(toSign);
var signed = fromNode.sign(uToSign);
var signedHex = bufferToHex(signed);
var signedHexNo0x = signedHex.substring(2);
where fromNode is the bip32.BIP32 node. Output is signedHexNo0x = 2711792b72547d2a1730a319bd219854f0892451b8bc2ab8c17ec0c6cba4ecc458f675ca0af3db455913e59dadc7c5e0bd0bf1b8ef8c13e830a627a18ac375ab.
At first sight, they seem completely different buffers, but after a detailed look, Blockcypher signer output only has some extra characters than that of bip32:
Blockcypher signer output (I split it into several lines for you to see it clearly):
30440220
2711792b72547d2a1730a319bd219854f0892451b8bc2ab8c17ec0c6cba4ecc4
0220
58f675ca0af3db455913e59dadc7c5e0bd0bf1b8ef8c13e830a627a18ac375ab
bip32 output (also intentionally split):
2711792b72547d2a1730a319bd219854f0892451b8bc2ab8c17ec0c6cba4ecc4
58f675ca0af3db455913e59dadc7c5e0bd0bf1b8ef8c13e830a627a18ac375ab
I'd expect two 64-character numbers to give a 128-characters signature, which bip32 output accomplishes. Hence, Blockcypher signer output has 140 characters, i.e. 12 more than the former, which is clear when seen as split into lines as above.
I'd be really thankful to anyone throwing some light on this issue, which I need to understand and correct. I need to implement the solution in dart, I cannot use the signer script other than for testing.
The dart bip32 package doesn't seem to encode the signature in DER format, but rather in a simple (r, s) encoding. However DER is required for Bitcoin. For more information see:
https://bitcoin.stackexchange.com/questions/92680/what-are-the-der-signature-and-sec-format
You can either add the DER extra bytes yourself according to your r and s or check if there's a DER encoding in the dart bip32 library.

How to do SSL public key pinning in flutter/dart?

relatively new to Flutter here (and programming in general). Only familiar with the more basic stuffs but I've now encountered the need to use a CertificatePinner such as this in flutter/dart:
https://square.github.io/okhttp/3.x/okhttp/okhttp3/CertificatePinner.html (I've successfully implemented this in my previous kotlin/java project in android studio). My goal is to pin public key (not certificate)
All I have is the public key in the form of a string like shown below, nothing else:
"sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="
How do I go about achieving this? I've asked this in an open issue on github but haven't gotten any responses yet (https://github.com/dart-lang/sdk/issues/35981). Hoping someone has managed to achieve this.
I've also scoured through other sources. I think the closest one to a solution for me is How can I do public key pinning in Flutter?
but I don't quite get what is being done there and I can't comment to ask questions there since I don't have enough reputation yet.
For comparison, all I want to do is achieve the same thing in flutter/dart what I could in java/kotlin with these few lines of code:
String hostname = "publicobject.com";
CertificatePinner certificatePinner = new CertificatePinner.Builder()
.add(hostname, "sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=")
.build();
Thanks for your help
Start with the code in the answer you refer to. That takes the certificate in DER format and starts decoding it.
ASN1Parser p = ASN1Parser(der);
ASN1Sequence signedCert = p.nextObject() as ASN1Sequence;
ASN1Sequence cert = signedCert.elements[0] as ASN1Sequence;
ASN1Sequence pubKeyElement = cert.elements[6] as ASN1Sequence;
// this is the Subject Public Key element, which describes the type of key and actual value
For example, if we decode the certificate of pub.dev we find that it's an RSA key with a modulus of 65537 and a value of 2347......:
SEQUENCE (2 elem)
SEQUENCE (2 elem)
OBJECT IDENTIFIER 1.2.840.113549.1.1.1 rsaEncryption (PKCS #1)
NULL
BIT STRING (1 elem)
SEQUENCE (2 elem)
INTEGER (2048 bit) 234782553149463204049153749736864715384123240676730175743244004248041…
INTEGER 65537
From the RFC, the SPKI fingerprint is the SHA-256 hash of this whole element.
// you need to import dart:convert and package:crypto/crypto.dart
var hash = base64.encode(sha256.convert(pubKeyElement.contentBytes()).bytes);
var spkiFingerprint = 'sha256/$hash'; // should match the value you have
Caveats
The badCertificateCallback doesn't deliver the whole certificate chain, so you can't walk up the whole chain. What's worse is that it doesn't always seem to deliver the leaf certificate! Sometimes it delivers an intermediate certificate.

Powershell and AES: If the Salt and IV are both fixed or known, is the encryption inherently unsafe or easier to crack?

I have recently been using this script to do some data encryption for a different script that I will later on be passing to other users, and I'm currently using a fixed IV and Salt. The reason I am currently using a fixed Salt and IV is that the data I have encrypted only needs to be encrypted once, but will need to be decrypted every time my script is run. As such, having everything fixed means that only the password needs to be known to other users of my script.
From reading around, it seems that having the Salt known does not make too much difference to the ease at which the data can be maliciously decrypted if it is unique, however I assume that by using a fixed Salt I am currently mooting the point of applying it.
My Password that I am passing into this script is entered at the point of encryption/decryption, and is not stored anywhere.
By keeping the Password completely secret, does this strengthen the encryption somewhat?
In addition, does anyone have any advice for a potentially safer implementation?
Many thanks for all help.
Salts and IV's serve the same purpose, preventing the re-use of work by starting at a random starting point. When you are hashing you call it a Salt, when you are encrypting you call it a IV.
Having a fixed Salt and VI is the same affect as having no Salt or IV, the entire point of those two things is they are different every time so if I crack the key on File A I can't reuse the work for File B, I have to start from scratch again.
Normally the Salt and IV are just prepended to the front of the file or are in the file header. When you go to decrypt the file you read in the IV/Salt first then start reading your encrypted data.
What I would do is instead of using a fixed salt and fixed IV I would just let the program generate the Salt and IV.
$r = new-Object System.Security.Cryptography.RijndaelManaged
$r.GenerateIV();
#generate a new instance of our KDF with a random 32 bit salt.
$deriveBytes = new-Object Security.Cryptography.Rfc2898DeriveBytes($Passphrase, 32)
$r.Key =$deriveBytes.GetBytes(32) #generate a 32 bit key based off of $Passphrase
#store $r.IV.Length, $r.IV, $deriveBytes.Salt at the front of your file ($deriveBytes.Salt we know will be 32 bytes big because we set it)
Further reading:
- Is it safe to have the salt equal to IV?
- Secret vs. Non-secret Initialization Vector
- Why would you need a salt [...] when IV is already randomly generated and stored with the encrypted data?

error in Blowfish.pm - input must be 8 bytes long

I am trying to encrypt plain text using the Perl's module Crypt::Blowfish.
My code is
#!/usr/bin/perl
use Crypt::Blowfish;
my $key = pack("H16", "0123456789ABCDEF");
my $cipher = Crypt::Blowfish->new($key);
my $cipher_text = $cipher->encrypt($plain_text);
But it returns the error ""input must be 8 bytes long at Crypt/Blowfish.pm"
Can anyone explain this to me?
Blowfish, like similar encryption algorithms, encrypts blocks rather than bytes. You need to use something like Crypt::CBC to provide padding.
Crypt::CBC also provides two other very important functions: salting and chaining. Without these, the encryption is severely weakened.

Generate RSA keypair in perl efficently with custom PRNG

I would want to generate a public and private keypair, effciently (fast) in perl, and be able to input random data for myself.
With inputting random data, I of course mean, that the function requires lets say X random bits to generate a public/private keypair of Y bits, and I should be able to supply these X bits to the function.
So idially, the function should look like:
($private, $public) = genRSAkeypair($randomdata, 1024);
and $private then contains:
----BEGIN RSA PRIVATE KEY-----
....
----END ....
and $public contains
----BEGIN RSA PUBLIC and so on...
$randomdata is then just a string of random bits from any random generator. If $randomdata is consistent between instance1 and instance2, instance1 and instance2 should return the same public and private keys.
If you want to know what the use of this is, is that I plan to make a password-based RSA key generation system, without any need to store any keys anywhere. So the key is generated straight out from the password, by using SHA512 chained in a specific way to create static random data.
Of course, the same public and private key must be returned everytime the same password is entered in the system, else the system would be useless.
Any ideas?
I would try Crypt::OpenSSL::RSA, it seems to bind
directly to libssl