ooxml_crypt 0.1.2 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Rakefile +1 -0
- data/ext/ooxml_crypt/extconf.rb +3 -2
- data/ext/ooxml_crypt/ooxml_crypt.c +3 -2
- data/lib/ooxml_crypt/version.rb +1 -1
- data/lib/ooxml_crypt.rb +8 -9
- data/ooxml_crypt.gemspec +34 -0
- data/vendor/cybozulib/include/cybozu/inttype.hpp +8 -9
- data/vendor/cybozulib/include/cybozu/serializer.hpp +17 -8
- data/vendor/cybozulib/include/cybozu/sha2.hpp +1 -1
- data/vendor/cybozulib/include/cybozu/string.hpp +10 -2
- data/vendor/msoffice/bin/.emptydir +0 -0
- data/vendor/msoffice/include/decode.hpp +2 -3
- data/vendor/msoffice/readme.md +2 -0
- metadata +6 -13
- data/vendor/msoffice/bin/64/msoc.dll +0 -0
- data/vendor/msoffice/bin/64/msocsample.exe +0 -0
- data/vendor/msoffice/bin/64/msoffice-crypt.exe +0 -0
- data/vendor/msoffice/bin/msoc.dll +0 -0
- data/vendor/msoffice/bin/msocsample.exe +0 -0
- data/vendor/msoffice/bin/msoffice-crypt.exe +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c7f876fbdff234101de69ca5a2b35cee3d12ad7cfb974548648f8e3d5abb7670
|
4
|
+
data.tar.gz: 8db6f0212c4d93a32c84ecb9fb7337c7d94eab425381fb3b3c88cfc8b2bd7ce3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0bc0fa7f78518b6d82a5a82725793475dcadc5d819fed25ae8c26c69e4b19dc4022ed7e73b7c7f41c5f0818d5d8892eb969f1bc77593f82354b98ca1f7fa1999
|
7
|
+
data.tar.gz: 9c6fb88936d15fbdf3a33b79604802a141be4f3f3c0c5bd643cd5794f9976ac29b140c37384cf075ccd22acf3eb8853c160f319d323384e3acdcff4703c7a33e
|
data/Rakefile
CHANGED
data/ext/ooxml_crypt/extconf.rb
CHANGED
@@ -6,7 +6,8 @@ require "mkmf"
|
|
6
6
|
have_library("stdc++")
|
7
7
|
|
8
8
|
# check for OpenSSL
|
9
|
-
|
9
|
+
openssl_present = pkg_config("openssl") || (have_header("openssl/hmac.h") && have_library("crypto"))
|
10
|
+
abort("Please install OpenSSL development libraries!") unless openssl_present
|
10
11
|
|
11
12
|
# setup build configuration
|
12
13
|
vendor = File.realpath(File.join(__dir__, "..", "..", "vendor"))
|
@@ -16,4 +17,4 @@ $VPATH << "#{vendor}/msoffice/src"
|
|
16
17
|
$srcs = ["ooxml_crypt.c", "msocdll.cpp"]
|
17
18
|
|
18
19
|
# create makefile
|
19
|
-
create_makefile("ooxml_crypt/
|
20
|
+
create_makefile("ooxml_crypt/native")
|
@@ -18,9 +18,10 @@ VALUE rb_decrypt_file(VALUE self, VALUE inFile, VALUE password, VALUE outFile)
|
|
18
18
|
return INT2FIX(MSOC_decryptA(out, in, pass, NULL));
|
19
19
|
}
|
20
20
|
|
21
|
-
void
|
21
|
+
void Init_native(void)
|
22
22
|
{
|
23
|
-
VALUE
|
23
|
+
VALUE parent = rb_define_module("OoxmlCrypt");
|
24
|
+
VALUE mod = rb_define_module_under(parent, "Native");
|
24
25
|
|
25
26
|
rb_define_module_function(mod, "encrypt_file", rb_encrypt_file, 3);
|
26
27
|
rb_define_module_function(mod, "decrypt_file", rb_decrypt_file, 3);
|
data/lib/ooxml_crypt/version.rb
CHANGED
data/lib/ooxml_crypt.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative "ooxml_crypt/version"
|
4
|
-
require_relative "ooxml_crypt/ooxml_crypt"
|
5
4
|
|
6
5
|
require "tempfile"
|
6
|
+
require "ooxml_crypt/native"
|
7
7
|
|
8
8
|
module OoxmlCrypt
|
9
9
|
class Error < StandardError; end
|
@@ -29,7 +29,7 @@ module OoxmlCrypt
|
|
29
29
|
raise EmptyPassword if password.nil? || password.empty?
|
30
30
|
raise FileNotFound, input unless File.exist?(input)
|
31
31
|
|
32
|
-
result =
|
32
|
+
result = Native.encrypt_file(input, password, output)
|
33
33
|
raise Error, ERRORS[-result] if result != 0
|
34
34
|
end
|
35
35
|
|
@@ -37,7 +37,7 @@ module OoxmlCrypt
|
|
37
37
|
raise EmptyPassword if password.nil? || password.empty?
|
38
38
|
raise FileNotFound, input unless File.exist?(input)
|
39
39
|
|
40
|
-
result =
|
40
|
+
result = Native.decrypt_file(input, password, output)
|
41
41
|
raise Error, ERRORS[-result] if result != 0
|
42
42
|
end
|
43
43
|
|
@@ -56,6 +56,7 @@ module OoxmlCrypt
|
|
56
56
|
private
|
57
57
|
|
58
58
|
def self.with_temp_files(data)
|
59
|
+
input = output = nil
|
59
60
|
input = Tempfile.new("ooxml_crypt_input", binmode: true)
|
60
61
|
input.write(data)
|
61
62
|
input.close
|
@@ -65,11 +66,9 @@ module OoxmlCrypt
|
|
65
66
|
|
66
67
|
yield input.path, output.path
|
67
68
|
|
68
|
-
|
69
|
-
|
70
|
-
input
|
71
|
-
output
|
72
|
-
|
73
|
-
result
|
69
|
+
File.binread(output.path)
|
70
|
+
ensure
|
71
|
+
input&.unlink
|
72
|
+
output&.unlink
|
74
73
|
end
|
75
74
|
end
|
data/ooxml_crypt.gemspec
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "lib/ooxml_crypt/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "ooxml_crypt"
|
7
|
+
spec.version = OoxmlCrypt::VERSION
|
8
|
+
spec.authors = ["Ashish Kulkarni"]
|
9
|
+
spec.email = ["ashish@kulkarni.dev"]
|
10
|
+
|
11
|
+
spec.summary = "Library for encrypting/decrypting password-protected Microsoft Office XML (OOXML) files (e.g. .docx, .xlsx, .pptx)"
|
12
|
+
spec.homepage = "https://github.com/teamsimplepay/ooxml_crypt"
|
13
|
+
spec.license = "MIT"
|
14
|
+
spec.required_ruby_version = ">= 2.6.0"
|
15
|
+
|
16
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
17
|
+
spec.metadata["source_code_uri"] = spec.homepage
|
18
|
+
|
19
|
+
# Specify which files should be added to the gem when it is released.
|
20
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
21
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
22
|
+
`git ls-files -z`.split("\x0").reject do |f|
|
23
|
+
(f == __FILE__) || f.match(%r{\A(?:(?:test|spec|features)/|\.(?:git|travis|circleci)|appveyor)})
|
24
|
+
end
|
25
|
+
end
|
26
|
+
spec.require_paths = ["lib"]
|
27
|
+
spec.extensions = ["ext/ooxml_crypt/extconf.rb"]
|
28
|
+
|
29
|
+
spec.add_development_dependency "bundler", "~> 2.2"
|
30
|
+
spec.add_development_dependency "rake", "~> 13.0"
|
31
|
+
spec.add_development_dependency "rake-compiler", "~> 1.1"
|
32
|
+
|
33
|
+
spec.metadata["msys2_mingw_dependencies"] = "openssl"
|
34
|
+
end
|
@@ -29,8 +29,10 @@
|
|
29
29
|
#endif
|
30
30
|
#endif
|
31
31
|
#else
|
32
|
+
#ifndef MCL_STANDALONE
|
32
33
|
#include <unistd.h> // for ssize_t
|
33
34
|
#endif
|
35
|
+
#endif
|
34
36
|
|
35
37
|
#ifndef CYBOZU_ALIGN
|
36
38
|
#ifdef _MSC_VER
|
@@ -60,6 +62,7 @@
|
|
60
62
|
#else
|
61
63
|
#define CYBOZU_ALLOCA(x) __builtin_alloca(x)
|
62
64
|
#endif
|
65
|
+
#define CYBOZU_ALIGNED_ALLOCA(x, align) (void*)(size_t(CYBOZU_ALLOCA((x)+(align)-1)) & ~(size_t(align)-1))
|
63
66
|
#endif
|
64
67
|
#ifndef CYBOZU_NUM_OF_ARRAY
|
65
68
|
#define CYBOZU_NUM_OF_ARRAY(x) (sizeof(x) / sizeof(*x))
|
@@ -72,16 +75,12 @@
|
|
72
75
|
#endif
|
73
76
|
#endif
|
74
77
|
#ifndef CYBOZU_ASSUME
|
75
|
-
#
|
76
|
-
#
|
77
|
-
|
78
|
-
#
|
79
|
-
#define CYBOZU_ASSUME(x) __assume(x)
|
80
|
-
#else
|
81
|
-
#define CYBOZU_ASSUME(x) if (!(x)) { __builtin_unreachable(); }
|
82
|
-
#endif
|
78
|
+
#if defined(__clang__)
|
79
|
+
#define CYBOZU_ASSUME(x) assert(x); __builtin_assume(x)
|
80
|
+
#elif defined(_MSC_VER) || defined(__ICC)
|
81
|
+
#define CYBOZU_ASSUME(x) assert(x); __assume(x)
|
83
82
|
#else
|
84
|
-
#define CYBOZU_ASSUME(x) assert(x)
|
83
|
+
#define CYBOZU_ASSUME(x) assert(x); if (!(x)) { __builtin_unreachable(); }
|
85
84
|
#endif
|
86
85
|
#endif
|
87
86
|
|
@@ -45,6 +45,14 @@ void reserve_if_exists(T& t, size_t size)
|
|
45
45
|
dispatch_reserve(t, size, 0);
|
46
46
|
}
|
47
47
|
|
48
|
+
// detect whether T::iterator exists
|
49
|
+
template <typename T>
|
50
|
+
struct has_iterator {
|
51
|
+
template <typename U> static char test(typename U::iterator*);
|
52
|
+
template <typename U> static int test(...);
|
53
|
+
static const bool value = sizeof(test<T>(0)) == 1;
|
54
|
+
};
|
55
|
+
|
48
56
|
} // serializer_local
|
49
57
|
|
50
58
|
template<class InputStream, class T>
|
@@ -257,10 +265,11 @@ void save(OutputStream& os, const char *x)
|
|
257
265
|
|
258
266
|
// for vector, list
|
259
267
|
template<class InputStream, class T, class Alloc, template<class T_, class Alloc_>class Container>
|
260
|
-
void load(Container<T, Alloc>& x, InputStream& is)
|
268
|
+
void load(Container<T, Alloc>& x, InputStream& is, typename stream_local::enable_if<serializer_local::has_iterator<Container<T, Alloc> >::value>::type* = 0)
|
261
269
|
{
|
262
270
|
size_t size;
|
263
271
|
load(size, is);
|
272
|
+
x.clear();
|
264
273
|
serializer_local::reserve_if_exists(x, size);
|
265
274
|
for (size_t i = 0; i < size; i++) {
|
266
275
|
x.push_back(T());
|
@@ -270,7 +279,7 @@ void load(Container<T, Alloc>& x, InputStream& is)
|
|
270
279
|
}
|
271
280
|
|
272
281
|
template<class OutputStream, class T, class Alloc, template<class T_, class Alloc_>class Container>
|
273
|
-
void save(OutputStream& os, const Container<T, Alloc>& x)
|
282
|
+
void save(OutputStream& os, const Container<T, Alloc>& x, typename stream_local::enable_if<serializer_local::has_iterator<Container<T, Alloc> >::value>::type* = 0)
|
274
283
|
{
|
275
284
|
typedef Container<T, Alloc> V;
|
276
285
|
save(os, x.size());
|
@@ -281,7 +290,7 @@ void save(OutputStream& os, const Container<T, Alloc>& x)
|
|
281
290
|
|
282
291
|
// for set
|
283
292
|
template<class InputStream, class K, class Pred, class Alloc, template<class K_, class Pred_, class Alloc_>class Container>
|
284
|
-
void load(Container<K, Pred, Alloc>& x, InputStream& is)
|
293
|
+
void load(Container<K, Pred, Alloc>& x, InputStream& is, typename stream_local::enable_if<serializer_local::has_iterator<Container<K, Pred, Alloc> >::value>::type* = 0)
|
285
294
|
{
|
286
295
|
size_t size;
|
287
296
|
load(size, is);
|
@@ -293,7 +302,7 @@ void load(Container<K, Pred, Alloc>& x, InputStream& is)
|
|
293
302
|
}
|
294
303
|
|
295
304
|
template<class OutputStream, class K, class Pred, class Alloc, template<class K_, class Pred_, class Alloc_>class Container>
|
296
|
-
void save(OutputStream& os, const Container<K, Pred, Alloc>& x)
|
305
|
+
void save(OutputStream& os, const Container<K, Pred, Alloc>& x, typename stream_local::enable_if<serializer_local::has_iterator<Container<K, Pred, Alloc> >::value>::type* = 0)
|
297
306
|
{
|
298
307
|
typedef Container<K, Pred, Alloc> Set;
|
299
308
|
save(os, x.size());
|
@@ -304,7 +313,7 @@ void save(OutputStream& os, const Container<K, Pred, Alloc>& x)
|
|
304
313
|
|
305
314
|
// for map
|
306
315
|
template<class InputStream, class K, class V, class Pred, class Alloc, template<class K_, class V_, class Pred_, class Alloc_>class Container>
|
307
|
-
void load(Container<K, V, Pred, Alloc>& x, InputStream& is)
|
316
|
+
void load(Container<K, V, Pred, Alloc>& x, InputStream& is, typename stream_local::enable_if<serializer_local::has_iterator<Container<K, V, Pred, Alloc> >::value>::type* = 0)
|
308
317
|
{
|
309
318
|
typedef Container<K, V, Pred, Alloc> Map;
|
310
319
|
size_t size;
|
@@ -318,7 +327,7 @@ void load(Container<K, V, Pred, Alloc>& x, InputStream& is)
|
|
318
327
|
}
|
319
328
|
|
320
329
|
template<class OutputStream, class K, class V, class Pred, class Alloc, template<class K_, class V_, class Pred_, class Alloc_>class Container>
|
321
|
-
void save(OutputStream& os, const Container<K, V, Pred, Alloc>& x)
|
330
|
+
void save(OutputStream& os, const Container<K, V, Pred, Alloc>& x, typename stream_local::enable_if<serializer_local::has_iterator<Container<K, V, Pred, Alloc> >::value>::type* = 0)
|
322
331
|
{
|
323
332
|
typedef Container<K, V, Pred, Alloc> Map;
|
324
333
|
save(os, x.size());
|
@@ -330,7 +339,7 @@ void save(OutputStream& os, const Container<K, V, Pred, Alloc>& x)
|
|
330
339
|
|
331
340
|
// unordered_map
|
332
341
|
template<class InputStream, class K, class V, class Hash, class Pred, class Alloc, template<class K_, class V_, class Hash_, class Pred_, class Alloc_>class Container>
|
333
|
-
void load(Container<K, V, Hash, Pred, Alloc>& x, InputStream& is)
|
342
|
+
void load(Container<K, V, Hash, Pred, Alloc>& x, InputStream& is, typename stream_local::enable_if<serializer_local::has_iterator<Container<K, V, Hash, Pred, Alloc> >::value>::type* = 0)
|
334
343
|
{
|
335
344
|
typedef Container<K, V, Hash, Pred, Alloc> Map;
|
336
345
|
size_t size;
|
@@ -346,7 +355,7 @@ void load(Container<K, V, Hash, Pred, Alloc>& x, InputStream& is)
|
|
346
355
|
}
|
347
356
|
|
348
357
|
template<class OutputStream, class K, class V, class Hash, class Pred, class Alloc, template<class K_, class V_, class Hash_, class Pred_, class Alloc_>class Container>
|
349
|
-
void save(OutputStream& os, const Container<K, V, Hash, Pred, Alloc>& x)
|
358
|
+
void save(OutputStream& os, const Container<K, V, Hash, Pred, Alloc>& x, typename stream_local::enable_if<serializer_local::has_iterator<Container<K, V, Hash, Pred, Alloc> >::value>::type* = 0)
|
350
359
|
{
|
351
360
|
typedef Container<K, V, Hash, Pred, Alloc> Map;
|
352
361
|
save(os, x.size());
|
@@ -37,7 +37,11 @@ namespace cybozu {
|
|
37
37
|
#if defined(__GNUC__) && (__SIZEOF_WCHAR_T__ == 4)
|
38
38
|
/* avoid to use uint32_t because compiling boost::regex fails */
|
39
39
|
typedef wchar_t Char; //!< Char for Linux
|
40
|
+
#if __cplusplus >= 201103L
|
41
|
+
typedef char16_t Char16;
|
42
|
+
#else
|
40
43
|
typedef unsigned short Char16; /* unsigned is necessary for gcc */
|
44
|
+
#endif
|
41
45
|
#else
|
42
46
|
typedef int Char; //!< Char for Windows
|
43
47
|
typedef wchar_t Char16;
|
@@ -1708,7 +1712,9 @@ void save(OutputStream& os, const cybozu::String& str)
|
|
1708
1712
|
namespace boost {
|
1709
1713
|
|
1710
1714
|
template<>
|
1711
|
-
struct hash<cybozu::String>
|
1715
|
+
struct hash<cybozu::String> {
|
1716
|
+
typedef cybozu::String argument_type;
|
1717
|
+
typedef size_t result_type;
|
1712
1718
|
size_t operator()(const cybozu::String& str) const
|
1713
1719
|
{
|
1714
1720
|
return static_cast<size_t>(cybozu::hash64(str.c_str(), str.size()));
|
@@ -1726,7 +1732,9 @@ CYBOZU_NAMESPACE_TR1_BEGIN
|
|
1726
1732
|
#endif
|
1727
1733
|
|
1728
1734
|
template<>
|
1729
|
-
struct hash<cybozu::String>
|
1735
|
+
struct hash<cybozu::String> {
|
1736
|
+
typedef cybozu::String argument_type;
|
1737
|
+
typedef size_t result_type;
|
1730
1738
|
size_t operator()(const cybozu::String& str) const
|
1731
1739
|
{
|
1732
1740
|
return static_cast<size_t>(cybozu::hash64(str.c_str(), str.size()));
|
File without changes
|
@@ -113,7 +113,6 @@ inline bool getAgileSecretKey(std::string& secretKey, const EncryptionInfo& info
|
|
113
113
|
inline bool decodeAgile(std::string& decData, const std::string& encryptedPackage, const EncryptionInfo& info, const std::string& pass, std::string& secretKey)
|
114
114
|
{
|
115
115
|
const CipherParam& keyData = info.keyData;
|
116
|
-
const CipherParam& encryptedKey = info.encryptedKey;
|
117
116
|
if (secretKey.empty()) {
|
118
117
|
if (!getAgileSecretKey(secretKey, info, pass)) return false;
|
119
118
|
if (putSecretKeyInstance()) {
|
@@ -130,8 +129,8 @@ inline bool decodeAgile(std::string& decData, const std::string& encryptedPackag
|
|
130
129
|
const uint64_t decodeSize = GetEncodedData(encData, encryptedPackage);
|
131
130
|
|
132
131
|
// decode
|
133
|
-
normalizeKey(secretKey,
|
134
|
-
DecContent(decData, encData,
|
132
|
+
normalizeKey(secretKey, keyData.keyBits / 8);
|
133
|
+
DecContent(decData, encData, keyData, secretKey, keyData.saltValue);
|
135
134
|
decData.resize(size_t(decodeSize));
|
136
135
|
return true;
|
137
136
|
}
|
data/vendor/msoffice/readme.md
CHANGED
metadata
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ooxml_crypt
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ashish Kulkarni
|
8
|
-
autorequire:
|
9
8
|
bindir: bin
|
10
9
|
cert_chain: []
|
11
|
-
date:
|
10
|
+
date: 2025-05-20 00:00:00.000000000 Z
|
12
11
|
dependencies:
|
13
12
|
- !ruby/object:Gem::Dependency
|
14
13
|
name: bundler
|
@@ -52,7 +51,6 @@ dependencies:
|
|
52
51
|
- - "~>"
|
53
52
|
- !ruby/object:Gem::Version
|
54
53
|
version: '1.1'
|
55
|
-
description:
|
56
54
|
email:
|
57
55
|
- ashish@kulkarni.dev
|
58
56
|
executables: []
|
@@ -71,6 +69,7 @@ files:
|
|
71
69
|
- ext/ooxml_crypt/ooxml_crypt.h
|
72
70
|
- lib/ooxml_crypt.rb
|
73
71
|
- lib/ooxml_crypt/version.rb
|
72
|
+
- ooxml_crypt.gemspec
|
74
73
|
- vendor/cybozulib/.github/workflows/main.yml
|
75
74
|
- vendor/cybozulib/.gitignore
|
76
75
|
- vendor/cybozulib/CMakeLists.txt
|
@@ -274,12 +273,7 @@ files:
|
|
274
273
|
- vendor/cybozulib/tool/vcproj_tmpl.py
|
275
274
|
- vendor/msoffice/COPYRIGHT
|
276
275
|
- vendor/msoffice/Makefile
|
277
|
-
- vendor/msoffice/bin
|
278
|
-
- vendor/msoffice/bin/64/msocsample.exe
|
279
|
-
- vendor/msoffice/bin/64/msoffice-crypt.exe
|
280
|
-
- vendor/msoffice/bin/msoc.dll
|
281
|
-
- vendor/msoffice/bin/msocsample.exe
|
282
|
-
- vendor/msoffice/bin/msoffice-crypt.exe
|
276
|
+
- vendor/msoffice/bin/.emptydir
|
283
277
|
- vendor/msoffice/common.mk
|
284
278
|
- vendor/msoffice/common.props
|
285
279
|
- vendor/msoffice/debug.props
|
@@ -328,7 +322,7 @@ licenses:
|
|
328
322
|
metadata:
|
329
323
|
homepage_uri: https://github.com/teamsimplepay/ooxml_crypt
|
330
324
|
source_code_uri: https://github.com/teamsimplepay/ooxml_crypt
|
331
|
-
|
325
|
+
msys2_mingw_dependencies: openssl
|
332
326
|
rdoc_options: []
|
333
327
|
require_paths:
|
334
328
|
- lib
|
@@ -343,8 +337,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
343
337
|
- !ruby/object:Gem::Version
|
344
338
|
version: '0'
|
345
339
|
requirements: []
|
346
|
-
rubygems_version: 3.
|
347
|
-
signing_key:
|
340
|
+
rubygems_version: 3.6.2
|
348
341
|
specification_version: 4
|
349
342
|
summary: Library for encrypting/decrypting password-protected Microsoft Office XML
|
350
343
|
(OOXML) files (e.g. .docx, .xlsx, .pptx)
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|