I hope this is the right forum; I was not sure if I should ask this in stackoverflow, cryptography or security.
So my problem is that php's hash_hmac function is only available with php >=5.1.2. Because some servers are not updated to this version I wrote my own HMAC-implementaion based on php's hash function. But the code doesn't produce the same output as hash_hmac...
So where is my mistake?
define("HASH_ALGO", "sha512");
define("HMAC_BLOCKSIZE", 64);
function computeHMAC($message, $key) {
$ikey;
$okey;
$zero = hex2bin("00");
$ipad = hex2bin("36");
$opad = hex2bin("5C");
/*
* HMAC construction scheme:
* $ikey = $key padded with zeroes to blocksize and then each byte xored with 0x36
* $okey = $key padded with zeroes to blocksize and then each byte xored with 0x5C
* hash($okey . hash($ikey . $message))
*/
//Hash key if it is larger than HMAC_BLOCKSIZE
if (strlen($key) > HMAC_BLOCKSIZE) {
$key = hash(HASH_ALGO, $key, true);
}
//Fill ikey with zeroes
for ($i = 0; $i < HMAC_BLOCKSIZE; $i++) {
$ikey[$i] = $zero;
}
//Fill ikey with the real key
for ($i = 0; $i < strlen($key); $i++) {
$ikey[$i] = $key[$i];
}
//Until they get xored both keys are equal
$okey = $ikey;
//Xor both keys
for ($i = 0; $i < HMAC_BLOCKSIZE; $i++) {
$ikey[$i] ^= $ipad;
$okey[$i] ^= $opad;
}
//Build inner hash
$innerHash = hash(HASH_ALGO, $ikey . $message, true);
//Build outer hash
$outerHash = hash(HASH_ALGO, $okey . $innerHash, true);
return $outerHash;
}
The function was tested with the following code:
echo hexDump(computeHMAC("Testolope", "Testkeyolope"));
echo hexDump(hash_hmac(HASH_ALGO, "Testolope", "Testkeyolope", true));
The output is the following:
HexDump (64 Bytes):
65 a8 81 af 49 f2 49 c5 64 7a 7a b7 a6 ac a0 4e 9e 9b 1a 3c 76 fc 48 19 13 33 e0 f8 82 be 48 52 1a 50 49 09 1e fe bf 94 63 5f 9d 36 82 3f 2f a1 43 b4 60 9f 9f e5 d1 64 c6 5b 32 22 45 07 c9 cb
HexDump (64 Bytes):
d2 e9 52 d2 ab f0 db a7 60 e0 52 b0 5c 23 5a 73 d9 8c 78 8e 9e fb 26 82 54 7e f9 c8 f1 65 df 7f 97 44 fe 2b 1e 2b 6d d5 cb a4 ba c6 73 35 06 9c 0f c8 2d 36 8c b3 9b c4 48 01 5c c2 9f ce b4 08
The problem is that you've mixed up the digest size and block size; SHA-512 has a digest size of 64, but a block size of 128.
Secondly, both $ikey and $okey are arrays and not strings, so you need to convert them both into a string first:
$innerHash = hash(HASH_ALGO, join($ikey) . $message, true);
$outerHash = hash(HASH_ALGO, join($okey) . $innerHash, true);
That said, both hash() and hash_hmac() are documented as being available since 5.1.2, so I'm not sure what this will achieve :)
Related
Looking to add a line break after every 16 bytes of the 100 bytes printed from j. All 100 bytes are currently printed on one line at the moment.
Any assistance would be great full, thanks.
for ($j = 6; $j < 106; $j++)
{
printf("%02X ", hex(#bytes[$j]));
}
printf("\t");
Thanks all. I approached it another way. In the end the visual aspect was not a concern as I ended up printing to file anyway. This data then gets pasted in a hex editor so formatting was a forethought rather than a need be. The below is now outputting all the data I was looking for in the end rather than a predetermined length.
for ($j = 6; $j < #bytes; $j = $j + 1)
{
printf outfile ("%02X ", hex(#bytes[$j]));
}
printf("\n");
Use splice() to grab 16 elements at a time from your array.
I've also switched to using say(), join(), map() and sprintf().
#!/usr/bin/perl
use strict;
use warnings;
use feature 'say';
my #bytes = map { int(rand(255)) } 0..200;
# As splice is destructive, take a copy of the array.
# Also, let's remove those first six elements and any
# after index 106.
my #data = #bytes[6 .. 105];
while (my #row = splice #data, 0, 16) {
say join ' ', map { sprintf '%02X', $_ } #row;
}
Update: A few more Perl tips for you.
Always add use strict and use warnings to the top of your Perl programs. And fix the problems they will show you.
#bytes[$j] is better written as $bytes[$j] (as it's a single value). That's one of the things use warnings will tell you about.
for ($j = 6; $j < 106; $j++) is probably better written as for my $j (6 .. 105). Less chance of "off-by-one" errors.
Actually, as you're just using $j to get the element from the array, you probably want to just iterate across the elements of the array directly - for my $elem (#bytes[6 .. 105]) (and then using $elem in place of $bytes[$j]).
You can utilize some $counter and print \n once $counter % 16 equal 0.
use strict;
use warnings;
my #bytes = map { int(rand(255)) } 0..200;
my $counter = 1;
for ( #bytes[6..106] ) {
printf "%02X ", $_;
print "\n" unless $counter++ % 16;
}
print "\n";
Output sample
C9 CA E7 66 13 F5 56 BE 08 68 E4 22 93 77 E0 14
08 4F F3 AD CC F4 66 DE 6C BB 1B E6 CE F3 13 DD
AE 6A CD 9B 5E 98 1F D4 2E C5 80 4B 3E 8E BC BF
5B 27 F9 0D 97 AB 26 C0 11 2D 1D 95 CE 26 3C D8
3C D8 A4 06 0A 48 0D 45 53 28 7E 5D D2 AD 90 5C
03 32 95 48 F6 DB 20 90 A7 62 41 3D D7 AB 7C 3B
CF 3D 0D C2 DA
Note: index from 6 to 106 gives 101 element
Short and fast:
sub hex_dump {
my $i = 0;
my $d = uc unpack 'H*', pack 'C*', #_;
$d =~ s{ ..\K(?!\z) }{ ++$i % 16 ? " " : "\n" }xseg;
return "$d\n";
}
print hex_dump(#bytes[6..105]);
There's also the very clean splice loop approach.
sub hex_dump {
my $d = '';
$d .= join(" ", map sprintf("%02X", $_), splice(#_, 0, 16)) . "\n" while #_;
return $d;
}
print hex_dump(#bytes[6..105]);
Because this approach produces a line at a time, it's great for recreating the traditional hex dump format (with offset and printable characters shown).
$ hexdump -C a.pl
00000000 75 73 65 20 73 74 72 69 63 74 3b 0a 75 73 65 20 |use strict;.use |
00000010 77 61 72 6e 69 6e 67 73 3b 0a 0a 73 75 62 20 68 |warnings;..sub h|
00000020 65 78 5f 64 75 6d 70 20 7b 0a 20 20 20 6d 79 20 |ex_dump {. my |
...
000000a0 74 65 73 20 3d 20 30 2e 2e 32 35 35 3b 0a 0a 70 |tes = 0..255;..p|
000000b0 72 69 6e 74 20 68 65 78 5f 64 75 6d 70 28 40 62 |rint hex_dump(#b|
000000c0 79 74 65 73 5b 36 2e 2e 31 30 35 5d 29 3b 0a |ytes[6..105]);.|
000000cf
You could also use a for loop. You would iterate over the indexes, and print either a space or a line feed depending on the index of the byte you're printing.
sub hex_dump {
my $d = '';
for my $i (0..$#_) {
$d .= sprintf("%02X%s", $_[$i], $i == $#_ || $i % 16 == 15 ? "\n" : " ");
}
return $d;
}
print hex_dump(#bytes[6..105]);
I have an ahk script for an IRC client which after entering nick!ident#host into the text field and pressing F4 decrypts the ident which is the encrypted form of the IP address:
F4::
Clipboard =
Send ^a^x
ClipWait, 0
If ErrorLevel
MsgBox, 48, Error, An error occurred while waiting for the clipboard. Aborting.
Else Clipboard := decode(SubStr(Clipboard, -15, -8))
Return
decode(str) {
Static code := " " "
( LTrim Join`s
00 0x 02 03 04 0z 06 01 08 09 0B 0b 0c 0d 0e 0H x0 xx x2 x3 x4 xz x6 x1 x8 x9 xB xb xc xd xe xH 20 2x
22 23 24 2z 26 21 28 29 2B 2b 2c 2d 2e 2H 30 3x 32 33 34 3z 36 31 38 39 3B 3b 3c 3d 3e 3H 40 4x 42 43
44 4z 46 41 48 49 4B 4b 4c 4d 4e 4H z0 zx z2 z3 z4 zz z6 z1 z8 z9 zB zb zc zd ze zH 60 6x 62 63 64 6z
66 61 68 69 6B 6b 6c 6d 6e 6H 10 1x 12 13 14 1z 16 11 18 19 1B 1b 1c 1d 1e 1H 80 8x 82 83 84 8z 86 81
88 89 8B 8b 8c 8d 8e 8H 90 9x 92 93 94 9z 96 91 98 99 9B 9b 9c 9d 9e 9H B0 Bx B2 B3 B4 Bz B6 B1 B8 B9
BB Bb Bc Bd Be BH b0 bx b2 b3 b4 bz b6 b1 b8 b9 bB bb bc bd be bH c0 cx c2 c3 c4 cz c6 c1 c8 c9 cB cb
cc cd ce cH d0 dx d2 d3 d4 dz d6 d1 d8 d9 dB db dc dd de dH e0 ex e2 e3 e4 ez e6 e1 e8 e9 eB eb ec ed
ee eH H0 Hx H2 H3 H4 Hz H6 H1 H8 H9 HB Hb Hc Hd He HH
)"
Loop, % StrLen(str) / 2
new .= "." Round((Instr(code, " " SubStr(str, 2 * A_Index - 1, 2), True) - 1) / 3)
Return SubStr(new, 2)
}
Decryption is performed according to the following key:
https://pastebin.com/raw/P8cQtH2v
For example, for user data asdf!~z3040d4B#webchat will decrypt the ident from z3040d4B as 83.4.13.75 and copies this value to the clipboard.
But there are cases when the encoded form of the IP (ident) is longer or shorter than 8 characters or contains characters that aren't in the decryption key. Then it's impossible to decode the IP correctly. So I would like the script to copy the decryption result to the clipboard only if the retrieved string (between ! and #, omitting the ~ sign if present) is 8 characters long and contains the characters contained in the key I entered. Otherwise, the script should clear the clipboard. How to do it?
A regex match approach with e.g the regex !~?[A-z\d]{8}# is surely most convenient:
F4::
Clipboard := ""
SendInput, ^a^x
ClipWait, 0
if (ErrorLevel)
MsgBox, 48, Error, An error occurred while waiting for the clipboard. Aborting.
else if (Clipboard ~= "!~?[A-z\d]{8}#")
Clipboard := decode(SubStr(Clipboard, -15, -8))
else
Clipboard := ""
Return
decode(str)
{
static code := " " "
( LTrim Join`s
00 0x 02 03 04 0z 06 01 08 09 0B 0b 0c 0d 0e 0H x0 xx x2 x3 x4 xz x6 x1 x8 x9 xB xb xc xd xe xH 20 2x
22 23 24 2z 26 21 28 29 2B 2b 2c 2d 2e 2H 30 3x 32 33 34 3z 36 31 38 39 3B 3b 3c 3d 3e 3H 40 4x 42 43
44 4z 46 41 48 49 4B 4b 4c 4d 4e 4H z0 zx z2 z3 z4 zz z6 z1 z8 z9 zB zb zc zd ze zH 60 6x 62 63 64 6z
66 61 68 69 6B 6b 6c 6d 6e 6H 10 1x 12 13 14 1z 16 11 18 19 1B 1b 1c 1d 1e 1H 80 8x 82 83 84 8z 86 81
88 89 8B 8b 8c 8d 8e 8H 90 9x 92 93 94 9z 96 91 98 99 9B 9b 9c 9d 9e 9H B0 Bx B2 B3 B4 Bz B6 B1 B8 B9
BB Bb Bc Bd Be BH b0 bx b2 b3 b4 bz b6 b1 b8 b9 bB bb bc bd be bH c0 cx c2 c3 c4 cz c6 c1 c8 c9 cB cb
cc cd ce cH d0 dx d2 d3 d4 dz d6 d1 d8 d9 dB db dc dd de dH e0 ex e2 e3 e4 ez e6 e1 e8 e9 eB eb ec ed
ee eH H0 Hx H2 H3 H4 Hz H6 H1 H8 H9 HB Hb Hc Hd He HH
)"
Loop, % StrLen(str) / 2
{
if (!InStr(code, block := " " SubStr(str, 2 * A_Index - 1, 2), true))
return ""
new .= "." Round((InStr(code, block, true) - 1) / 3)
}
return SubStr(new, 2)
}
~=(docs) is the RegExMatch()(docs) shorthand.
I have this code (can be run in a playground):
import UIKit
import CryptoKit
let url: URL = URL(string: "https://apple.com")!
final class SSLExtractor: NSObject, URLSessionDelegate {
private var session: URLSession!
init(url: URL) {
super.init()
let session = URLSession.init(configuration: .default, delegate: self, delegateQueue: nil)
session.dataTask(with: url).resume()
}
func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: #escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
guard challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust,
let serverTrust = challenge.protectionSpace.serverTrust,
let publicKey = SecTrustCopyKey(serverTrust),
let publicKeyData = SecKeyCopyExternalRepresentation(publicKey, nil)
else { return }
let publicKeyHash = SHA256.hash(data: publicKeyData as Data)
print("publicKey: \(publicKey)")
print("publicKey: \(publicKeyData)")
print("publicKey: \((publicKeyData as Data).base64EncodedString() )")
print(publicKeyHash)
}
}
let extractor = SSLExtractor(url: url)
Supposedly the last print should give me the server's public key:
SHA256 digest: b0faa00170de7c1ac7994644efadb59f149656546394bd22c95527e78f1984b6
However, when I use OpenSSL:
$ openssl s_client -connect apple.com:443 | openssl x509 -pubkey -noout | openssl rsa -pubin -outform der| openssl dgst -sha256
I get a different hash:
1786e93d8e16512ea34ea1475e39597e77d7e39239ba1a97dcd71f97e64d6619
How to get the correct hash ?
Edit: Also tried
let certificate = SecTrustGetCertificateAtIndex(serverTrust, 0),
let certifKey = SecCertificateCopyKey(certificate),
let certifPubKey = SecKeyCopyPublicKey(certifKey),
let certifPubKeyData = SecKeyCopyExternalRepresentation(certifPubKey, nil)
But I got the same result
Only sort of an answer but too much for comments. You found that the 'external' publickey provided (and hashed) by Swift is a suffix of that used by OpenSSL.
OpenSSL uses, as I referenced, the 'SPKI' (SubjectPublicKeyInfo) structure defined by X.509/PKIX=RFC5280 section 4 which is a DER-encoded ASN.1 SEQUENCE containing an AlgorithmIdentifier and a BIT STRING cotaining embedded algorithm-specific data. RFC 7468 section 13 (which partly officializes OpenSSL, although it doesn't say so) confirms this is the content of a 'standard' public key representation, and RFC 3279 section 2.3.1 defines that for RSA (which the Apple cert's key is) the content of the BIT STRING part is the ASN.1 structure RSAPublicKey which actually was defined (though 3279 doesn't say so for the key, while it does for the signature in 2.2.1) in PKCS1 currently RFC8017 section A.1.1 (but unchanged from earlier versions).
Because of the way DER encoding works, the content of the BIT STRING -- in this case the ASN.1 structure RSAPublicKey -- is exactly a suffix of the encoding of the whole SPKI.
If we look at, and parse, the SPKI OpenSSL gets from the cert (with x509 -pubkey)
$ openssl rsa -pubin -in applespki -outform der |od -Ax -tx1
writing RSA key
000000 30 82 01 22 30 0d 06 09 2a 86 48 86 f7 0d 01 01
000010 01 05 00 03 82 01 0f 00 30 82 01 0a 02 82 01 01
000020 00 e0 e5 ca aa 34 ea 32 d1 f5 e3 56 e5 05 e8 07
000030 c3 d3 3b 86 93 60 94 37 20 9f 8d d0 17 8f ba da
000040 16 f1 b2 6a bc 41 7a 6f dc 22 87 4b 05 e8 57 48
000050 56 3c da a2 02 e5 57 73 94 95 18 dd 7c c9 b0 68
000060 fe 17 2c 8b 6f fa 42 a9 b1 a8 77 88 22 d4 41 08
000070 08 d9 80 59 92 bc e9 3a 0a 17 e0 2b 13 fe bf ec
000080 69 7d 61 15 14 21 71 73 a0 70 fd 6d a0 0f 46 13
000090 60 8d c1 bd 8c 66 60 04 05 e0 44 f0 a1 53 b7 00
0000a0 7f a3 f3 55 da d2 6c c6 dd 7f 83 79 1f 6e cb 1d
0000b0 78 3e d9 9f fa 58 34 38 41 c5 70 c1 c7 dd ea b0
0000c0 81 c0 d4 a3 18 a4 da 02 15 b8 cb 48 10 fa 42 86
0000d0 75 1c 55 51 6b 48 6e 37 43 98 09 af 4f 52 c0 c8
0000e0 75 40 a5 e7 65 ba 62 2a be 6c 2a 6d 72 5b 82 21
0000f0 d1 75 97 ea 7e 21 a1 04 f4 76 7c 85 db 50 c7 9f
000100 b5 d8 f7 80 15 ba a5 83 9e 2c da f0 73 c6 14 9a
000110 fd 35 07 41 4b 53 21 8d 0d 01 f1 05 b3 04 05 83
000120 cb 02 03 01 00 01
000126
$ openssl asn1parse -i -dump -in applespki1
0:d=0 hl=4 l= 290 cons: SEQUENCE
4:d=1 hl=2 l= 13 cons: SEQUENCE
6:d=2 hl=2 l= 9 prim: OBJECT :rsaEncryption
17:d=2 hl=2 l= 0 prim: NULL
19:d=1 hl=4 l= 271 prim: BIT STRING
0000 - 00 30 82 01 0a 02 82 01-01 00 e0 e5 ca aa 34 ea .0............4.
0010 - 32 d1 f5 e3 56 e5 05 e8-07 c3 d3 3b 86 93 60 94 2...V......;..`.
0020 - 37 20 9f 8d d0 17 8f ba-da 16 f1 b2 6a bc 41 7a 7 ..........j.Az
0030 - 6f dc 22 87 4b 05 e8 57-48 56 3c da a2 02 e5 57 o.".K..WHV<....W
0040 - 73 94 95 18 dd 7c c9 b0-68 fe 17 2c 8b 6f fa 42 s....|..h..,.o.B
0050 - a9 b1 a8 77 88 22 d4 41-08 08 d9 80 59 92 bc e9 ...w.".A....Y...
0060 - 3a 0a 17 e0 2b 13 fe bf-ec 69 7d 61 15 14 21 71 :...+....i}a..!q
0070 - 73 a0 70 fd 6d a0 0f 46-13 60 8d c1 bd 8c 66 60 s.p.m..F.`....f`
0080 - 04 05 e0 44 f0 a1 53 b7-00 7f a3 f3 55 da d2 6c ...D..S.....U..l
0090 - c6 dd 7f 83 79 1f 6e cb-1d 78 3e d9 9f fa 58 34 ....y.n..x>...X4
00a0 - 38 41 c5 70 c1 c7 dd ea-b0 81 c0 d4 a3 18 a4 da 8A.p............
00b0 - 02 15 b8 cb 48 10 fa 42-86 75 1c 55 51 6b 48 6e ....H..B.u.UQkHn
00c0 - 37 43 98 09 af 4f 52 c0-c8 75 40 a5 e7 65 ba 62 7C...OR..u#..e.b
00d0 - 2a be 6c 2a 6d 72 5b 82-21 d1 75 97 ea 7e 21 a1 *.l*mr[.!.u..~!.
00e0 - 04 f4 76 7c 85 db 50 c7-9f b5 d8 f7 80 15 ba a5 ..v|..P.........
00f0 - 83 9e 2c da f0 73 c6 14-9a fd 35 07 41 4b 53 21 ..,..s....5.AKS!
0100 - 8d 0d 01 f1 05 b3 04 05-83 cb 02 03 01 00 01 ...............
we can see the content of the BIT STRING, skipping the first byte 00 because of the way DER works for BIT STRING, and thus starting at offset 24=0x18 and continuing to the end, is itself a DER encoding of RSAPublicKey (30 82 01 0a is the SEQUENCE, 02 82 01 01 ... is the INTEGER (signed) modulus, 02 03 01 00 01 is the INTEGER (signed) publicExponent). OpenSSL 1.0.0 up (which is now ubiquitous, though I remember when it wasn't) can extract this, and get your expected hash:
$ openssl rsa -pubin -in applespki -RSAPublicKey_out -outform der |od -Ax -tx1
writing RSA key
000000 30 82 01 0a 02 82 01 01 00 e0 e5 ca aa 34 ea 32
000010 d1 f5 e3 56 e5 05 e8 07 c3 d3 3b 86 93 60 94 37
000020 20 9f 8d d0 17 8f ba da 16 f1 b2 6a bc 41 7a 6f
000030 dc 22 87 4b 05 e8 57 48 56 3c da a2 02 e5 57 73
000040 94 95 18 dd 7c c9 b0 68 fe 17 2c 8b 6f fa 42 a9
000050 b1 a8 77 88 22 d4 41 08 08 d9 80 59 92 bc e9 3a
000060 0a 17 e0 2b 13 fe bf ec 69 7d 61 15 14 21 71 73
000070 a0 70 fd 6d a0 0f 46 13 60 8d c1 bd 8c 66 60 04
000080 05 e0 44 f0 a1 53 b7 00 7f a3 f3 55 da d2 6c c6
000090 dd 7f 83 79 1f 6e cb 1d 78 3e d9 9f fa 58 34 38
0000a0 41 c5 70 c1 c7 dd ea b0 81 c0 d4 a3 18 a4 da 02
0000b0 15 b8 cb 48 10 fa 42 86 75 1c 55 51 6b 48 6e 37
0000c0 43 98 09 af 4f 52 c0 c8 75 40 a5 e7 65 ba 62 2a
0000d0 be 6c 2a 6d 72 5b 82 21 d1 75 97 ea 7e 21 a1 04
0000e0 f4 76 7c 85 db 50 c7 9f b5 d8 f7 80 15 ba a5 83
0000f0 9e 2c da f0 73 c6 14 9a fd 35 07 41 4b 53 21 8d
000100 0d 01 f1 05 b3 04 05 83 cb 02 03 01 00 01
00010e
$ openssl rsa -pubin -in applespki -RSAPublicKey_out -outform der |openssl sha256
writing RSA key
(stdin)= b0faa00170de7c1ac7994644efadb59f149656546394bd22c95527e78f1984b6
This only works for RSA. It might be interesting to see how your Swift code handles a certificated non-RSA key, although at present those are hard to find on the public web; the only stable ones I currently know of are at 'badssl' like https://ecc256.badssl.com .
I'm looking at an RSA private key in PEM format. When I decode the base64 string and review the components of the key, some of them have an extra byte, specifically the modulus, P, DP, and IQ. They all have a leading 0x00 byte. I'm handling this by just trimming the byte[] down to the expected lengths of 256 or 128 so I can use them with .NET RSAParameters and RSACryptoServiceProvider, but wondering why some of these INTEGER structures have the extra byte while others don't. It would appear that online and other libraries that decode the PEM to XML, etc handle this gracefully, so is this part of the RFC, just something that you have to protect against, or only a concern because I'm using the .NET libraries after decoding? Here's an example of the modulus with 257 bytes:
00 B7 55 AA 3F 14 89 BC CE ED AF 80 1C 54 2A DF
AB 3C 6A 44 B4 55 58 90 0E 0D 32 96 E6 EF 35 2D
AD B7 44 A7 AB CE 6F D3 BB 9D B4 4B FD 0A DE 87
96 03 55 23 81 49 FE 1B 3E CE 62 B6 2F B1 4C 33
E4 F8 C2 09 5F 0E 10 78 22 D0 F3 C9 BF B9 AC AC
11 00 17 28 09 23 10 D5 8A C9 2B E2 86 96 A7 E2
57 68 D7 3B 63 BE 74 ED B8 02 E2 63 EF F5 40 85
0C A6 9F D0 B6 88 36 8B 4E 6B 35 27 BE 11 CC C8
C3 0A 66 25 E0 AB B6 DD 6D E6 2B AF 9E 1C D7 11
CE 5F E7 C8 1F EB 3D 79 B3 B2 E1 FF D8 20 6D 76
A2 43 9E 20 67 58 97 39 46 D8 73 F6 F0 76 01 E0
61 8E 4A EE C4 03 A6 44 C7 D3 50 E3 C8 62 CF 33
D1 37 6B 85 F5 D4 3C 6D 1F 1A 14 B3 30 B5 E0 82
A5 94 83 4F 7A 17 DA 86 2B F7 2A 47 A3 5F D2 D5
7B 96 32 86 27 5E 2A 6A 85 6E C6 24 15 A9 09 65
BB 04 8C 0D 39 F7 15 D4 F0 F8 5F 0F B0 1D A7 2F
D7
Here's an example of the "D" parameter that is not padded with a leading 0x00:
04 07 EF 8A 5D 88 3D C7 8B 00 5D DF C1 96 03 BE
FF 20 1D 0C A8 07 BF 7B 1F 9D 2A 26 3F C2 3A 93
E4 40 B5 33 18 E1 EA 94 E8 7D C0 61 EF F8 3E A0
F4 C7 CD 75 0D 4C 72 0A EA 7C CF 26 B3 4E 4A A1
D1 3A 6A FA 55 11 D5 A2 66 57 C5 EA DA 49 4A AB
41 06 41 52 1A 1C 47 A5 BA 90 A5 75 72 20 94 E0
79 24 AA 60 A2 12 6E 1B AA AC 91 A7 F8 0B 88 21
64 14 85 81 4D F3 6D 12 B7 56 BE DD F6 04 3B B1
CC 95 A6 8C 9D A6 8D BF 05 C1 72 A4 0B 03 75 F6
40 B6 8E 25 91 3D 87 84 CD 23 EF 2C 29 13 DD A7
75 6E 48 F4 DE 49 98 4F B7 09 CF 5A A3 F5 39 05
37 C8 2B 79 64 F0 B8 AD 11 EF 79 FD 78 C0 6B 2B
50 7F DE BC 59 3D D1 A1 90 59 B7 7E 57 B4 2C A0
D2 20 D2 D6 7C 4A B3 3C 63 5D FA E6 67 18 58 AC
F3 EF 0E E1 C0 C9 B6 D9 8C D1 8E 3D CE 8A FF F0
12 BF C2 FE 72 DC 07 E4 3C 00 5B BE 05 D9 5A 61
And the DP parameter without leading 0:
3E 50 B2 28 A3 B1 71 F3 D5 31 B1 2D FD B3 60 4B
57 F8 C1 46 C7 89 B7 95 F4 7D AE 54 F2 EA 11 98
F7 61 93 30 50 D9 24 19 BF 7F 06 19 DB 97 01 06
8B 20 D7 7A 5E 1A FA 76 9A 0E 27 46 AB FF 25 3C
74 61 E2 9B 3E CE A5 F9 58 40 70 15 94 F2 58 3E
DB E4 90 91 3C 50 B0 24 8F C7 A7 55 EB E3 59 A7
5D 01 19 29 4F F9 F9 E6 EB 78 D1 93 14 61 E4 5C
36 D7 E7 82 58 E7 C5 60 21 F3 1E 5A D4 49 C6 D1
The RSA modulus is a positive number, and ASN.1 integers are all signed.
So if the leading 0x00 wasn't there, this byte encoding would represent a negative number because the first byte would have the high bit set (0xB7 >= 0x80). As a consequence, the 0x00 gets inserted into the DER data stream.
.NET's representation is based on the Windows CAPI representation. CAPI uses domain knowledge to know that the values are all unsigned integers, and then omits the leading 0x00 bytes. So it's up to whoever translates between the DER data and the .NET/CAPI data to add or remove the bytes as needed.
These values are encoded as INTEGER ASN type which uses two-complement notation. That is if most significant bit is set to 1, then the number is negative. However, all numbers (modulus, exponents, primes) in key are positive numbers and prepended with extra leading zero octet to denote positive integer. If the most significant bit is already set to 0, then no extra bytes are added.
I need to split a Text in blocs, where the size of every bloc is 16,
For example:
Text:
60 3d eb 10 15 ca 71 be 2b 73 ae f0 85 7d 77 81 1f 35 2c 07 3b 61 08 d7 2d 98 10 a3 09 14 df f4 60 3d eb 10 15 ca 71 be 2b 73 ae f0 85 7d 77 81 1f 35 2c 07 3b 61 08 d7 2d 98 10 a3 09 14 df f4
Result:
60 3d eb 10 15 ca 71 be 2b 73 ae f0 85 7d 77 81
1f 35 2c 07 3b 61 08 d7 2d 98 10 a3 09 14 df f4
60 3d eb 10 15 ca 71 be 2b 73 ae f0 85 7d 77 81
1f 35 2c 07 3b 61 08 d7 2d 98 10 a3 09 14 df f4
I would be very grateful if you could help me.
You can just read this in using fread and then reshape the data.
fid = fopen('filename.txt', 'r');
alldata = fread(fid, '*char');
data = reshape(alldata, 3*16, []).';
fclose(fid)
If you want something a little more robust, you could use textscan.
fid = fopen('filename.txt', 'r');
alldata = textscan(fid, '%s');
data = cell2mat(reshape(alldata{1}, 32, [])).';
fclose(fid)
If the spaces are important, you can use strjoin to maintain the spaces
tmp = reshape(alldata{1}, 16, []).';
tmp = arrayfun(#(x)strjoin(tmp(x,:)), 1:size(tmp, 1), 'uniformoutput', false);
data = cat(1, tmp{:})