Giter VIP home page Giter VIP logo

bluersa's Introduction

APIDoc Build Status - Master macOS iOS Linux Apache 2 Slack Status

BlueRSA

Swift cross-platform RSA wrapper library for RSA encryption and signing. Works on supported Apple platforms (using Security framework). Linux (using OpenSSL) is working but is still somewhat of a work in progress.

Contents

  • CryptorRSA: Utility functions for RSA encryption and signing. Pure Swift

Prerequisites

Swift

  • Swift Open Source swift-4.0.0-RELEASE toolchain (Minimum REQUIRED for latest release)
  • Swift Open Source swift-4.2-RELEASE toolchain (Recommended)
  • Swift toolchain included in Xcode Version 10.0 (10A255) or higher.

macOS

  • macOS 10.12.0 (Sierra) or higher
  • Xcode Version 9.0 (9A325) or higher using the included toolchain (Minimum REQUIRED for latest release).
  • Xcode Version 10.0 (10A255) or higher using the included toolchain (Recommended).

iOS

  • iOS 10.3 or higher
  • Xcode Version 9.0 (9A325) or higher using the included toolchain (Minimum REQUIRED for latest release).
  • Xcode Version 10.0 (10A255) or higher using the included toolchain (Recommended).

Linux

  • Ubuntu 16.04 (or 16.10 but only tested on 16.04) and 18.04.
  • One of the Swift Open Source toolchain listed above.
  • OpenSSL is provided by the distribution. Note: 1.0.x, 1.1.x and later releases of OpenSSL are supported.
  • The appropriate libssl-dev package is required to be installed when building.

Build

To build CryptorRSA from the command line:

% cd <path-to-clone>
% swift build

Testing

To run the supplied unit tests for CryptorRSA from the command line:

% cd <path-to-clone>
% swift build
% swift test

Using CryptorRSA

Including in your project

Swift Package Manager

To include BlueRSA into a Swift Package Manager package, add it to the dependencies attribute defined in your Package.swift file. You can select the version using the majorVersion and minor parameters. For example:

	dependencies: [
		.Package(url: "https://github.com/Kitura/BlueRSA", majorVersion: <majorVersion>, minor: <minor>)
	]

Carthage

To include BlueRSA in a project using Carthage, add a line to your Cartfile with the GitHub organization and project names and version. For example:

	github "Kitura/BlueRSA" ~> <majorVersion>.<minor>

Before starting

The first you need to do is import the CryptorRSA framework. This is done by the following:

import CryptorRSA

Data Types

BlueRSA supports the following major data types:

  • Key Handling

    • CryptorRSA.PublicKey - Represents an RSA Public Key.
    • CryptorRSA.PrivateKey - Represents an RSA Private Key.
  • Data Handling

    • CryptorRSA.EncryptedData - Represents encrypted data.
    • CryptorRSA.PlaintextData - Represents plaintext or decrypted data.
    • CryptorRSA.SignedData - Represents signed data.

Key Handling

BlueRSA provides seven (7) functions each for creating public and private keys from data. They are as follows (where createXXXX is either createPublicKey or createPrivateKey depending on what you're trying to create):

  • CryptorRSA.createXXXX(with data: Data) throws - This creates either a private or public key containing the data provided. It is assumed that the data being provided is in the proper format.
  • CryptorRSA.createXXXX(withBase64 base64String: String) throws - This creates either a private or public key using the Base64 encoded String provided.
  • CryptorRSA.createXXXX(withPEM pemString: String) throws - This creates either a private or public key using the PEM encoded String provided.
  • CryptorRSA.createXXXX(withPEMNamed pemName: String, onPath path: String) throws - This creates either a private or public key using the PEM encoded file pointed at by the pemName and located on the path specified by path provided.
  • CryptorRSA.createXXXX(withDERNamed derName: String, onPath path: String) throws - This creates either a private or public key using the DER encoded file pointed at by the derName and located on the path specified by path provided.
  • CryptorRSA.createXXXX(withPEMNamed pemName: String, in bundle: Bundle = Bundle.main) throws - This creates either a private or public key using the PEM encoded file pointed at by the pemName and located in the Bundle specified by bundle provided. By default this API will look in the main bundle. Note: Apple Platforms Only
  • CryptorRSA.createXXXX(withDERNamed derName: String, in bundle: Bundle = Bundle.main) throws - This creates either a private or public key using the DER encoded file pointed at by the derName and located in the Bundle specified by bundle provided. By default this API will look in the main bundle. Note: Apple Platforms Only

Additionally, there are three APIs for creating a public key by extracting the key from a PEM formatted certificate: They are:

  • CryptorRSA.createPublicKey(extractingFrom data: Data) throws - This creates either a public key by extracting from the PEM encoded certificate pointed at by the data.
  • CryptorRSA.createPublicKey(extractingFrom certName: String, onPath path: String) throws - This creates a public key by extracting from the PEM encoded certificate pointed at by the certName and located on the path specified by path provided.
  • CryptorRSA.createPublicKey(extractingFrom certName: String, in bundle: Bundle = Bundle.main) throws - This creates a public key using the PEM encoded certificate pointed at by the derName and located in the Bundle specified by bundle provided. By default this API will look in the main bundle. Note: Apple Platforms Only

Example

The following example illustrates creating a public key given PEM encoded file located on a certain path. *Note: Exception handling omitted for brevity.

import Foundation
import CryptorRSA

...

let keyName = ...
let keyPath = ...

let publicKey = try CryptorRSA.createPublicKey(withPEMNamed: keyName, onPath: keyPath)

...

<Do something with the key...>

Data Encryption and Decryption Handling

BlueRSA provides functions for the creation of each of the three (3) data handling types:

Plaintext Data Handling and Signing

There are two class level functions for creating a PlaintextData object. These are:

  • CryptorRSA.createPlaintext(with data: Data) -> PlaintextData - This function creates a PlaintextData containing the specified data.
  • CryptorRSA.createPlaintext(with string: String, using encoding: String.Encoding) throws -> PlaintextData - This function creates a PlaintextData object using the string encoded with the specified encoding as the data.

Once the PlaintextData object is created, there are two instance functions that can be used to manipulate the contained data. These are:

  • encrypted(with key: PublicKey, algorithm: Data.Algorithm) throws -> EncryptedData? - This function allows you to encrypt containing data using the public key and algorithm specified. This function returns an optional EncryptedData object containing the encryped data.
  • signed(with key: PrivateKey, algorithm: Data.Algorithm) throws -> SignedData? - This function allows you to sign the contained data using the private key and algorithm specified. This function returns an optional SignedData object containing the signature of the signed data.

Example

  • Encryption: Note: Exception handling omitted for brevity.
import Foundation
import CryptorRSA

...

let keyName = ...
let keyPath = ...

let myData: Data = <... Data to be encrypted ...>

let publicKey = try CryptorRSA.createPublicKey(withPEMNamed: keyName, onPath: keyPath)
let myPlaintext = CryptorRSA.createPlaintext(with: myData)
let encryptedData = try myPlaintext.encrypt(with: publicKey, algorithm: .sha1)

...

< Do something with the encrypted data...>

  • Signing: Note: Exception handling omitted for brevity.
import Foundation
import CryptorRSA

...

let keyName = ...
let keyPath = ...

let myData: Data = <... Data to be signed ...>

let privateKey = try CryptorRSA.createPrivateKey(withPEMNamed: keyName, onPath: keyPath)
let myPlaintext = CryptorRSA.createPlaintext(with: myData)
let signedData = try myPlaintext.signed(with: privateKey, algorithm: .sha1)

...

< Do something with the signed data...>

Encrypted Data Handling

There are two class level functions for creating a EncryptedData object. These are:

  • CryptorRSA.createEncrypted(with data: Data) -> EncryptedData - This function creates a EncryptedData containing the specified encrypted data.
  • CryptorRSA.createEncrypted(with base64String: String) throws -> EncryptedData - This function creates a EncrpytedData using the Base64 representation of already encrypted data.

Once the EncryptedData object is created, there is an instance function that can be used to decrypt the enclosed data:

  • decrypted(with key: PrivateKey, algorithm: Data.Algorithm) throws -> DecryptedData? - This function allows you to decrypt containing data using the public key and algorithm specified. This function returns an optional DecryptedData object containing the encryped data.

BlueRSA currently supports OAEP padding, which is the recommended padding algorithm.

Example

  • Decryption: Note: Exception handling omitted for brevity.
import Foundation
import CryptorRSA

...

let keyName = ...
let keyPath = ...
let publicKey = try CryptorRSA.createPublicKey(withPEMNamed: keyName, onPath: keyPath)

let pkeyName = ...
let pkeyPath = ...
let privateKey = try CryptorRSA.createPrivateKey(withPEMNamed: pkeyName, onPath: pkeyPath)

let myData: Data = <... Data to be encrypted ...>

let myPlaintext = CryptorRSA.createPlaintext(with: myData)
let encryptedData = try myPlaintext.encrypt(with: publicKey, algorithm: .sha1)

let decryptedData = try encryptedData.decrypt(with: privateKey, algorithm: .sha1)

...

< Do something with the decrypted data...>


Signature Verification Handling

There is a single class level function that can be used to create a SignedData object. It is:

  • CryptorRSA.createSigned(with data: Data) -> SignedData - This function creates a SignedData containing the specified signed data.

Once created or obtained PlaintextData and SignedData, there is an instance function which can be used to verify the signature contained therein:

  • verify(with key: PublicKey, signature: SignedData, algorithm: Data.Algorithm) throws -> Bool - This function is used to verify, using the public key and algorithm, the signature. Returns true if the signature is valid, false otherwise.

  • Verifying: Note: Exception handling omitted for brevity.

import Foundation
import CryptorRSA

...

let keyName = ...
let keyPath = ...
let publicKey = try CryptorRSA.createPublicKey(withPEMNamed: keyName, onPath: keyPath)

let pkeyName = ...
let pkeyPath = ...
let privateKey = try CryptorRSA.createPrivateKey(withPEMNamed: pkeyName, onPath: pkeyPath)

let myData: Data = <... Data to be signed ...>

let myPlaintext = CryptorRSA.createPlaintext(with: myData)
let signedData = try myPlaintext.signed(with: privateKey, algorithm: .sha1)

if try myPlaintext.verify(with: publicKey, signature: signedData, algorithm: .sha1) {

	print("Signature verified")

} else {

	print("Signature Verification Failed")
}

Data Type Utility Functions

All three of the data handling types have two common utility instance functions. These are:

  • digest(using algorithm: Data.Algorithm) throws -> Data - This function returns a Data object containing a digest constructed using the specified algorithm.
  • string(using encoding: String.Encoding) throws -> String - This functions returns a String representation of the data using the specified encoding.

Community

We love to talk server-side Swift and Kitura. Join our Slack to meet the team!

License

This library is licensed under Apache 2.0. Full license text is available in LICENSE.

bluersa's People

Contributors

andrew-lees11 avatar billabt avatar dannys42 avatar djones6 avatar gtaban avatar helenmasters avatar ianpartridge avatar kyemaloy97 avatar levi avatar mbarnach avatar r-plus avatar stmitt avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

bluersa's Issues

ERROR ITMS-90056 The Info.plist file is missing the required key: CFBundleVersion

When submitting to the app store I'm getting this error when including BlueRSA via Carthage.

I think the fix is to add CURRENT_PROJECT_VERSION to the Xcode project settings, and I will post a PR for that shortly.

ERROR ITMS-90056: "This bundle Payload/Application.app/Frameworks/CryptorRSA.framework is invalid. The Info.plist file is missing the required key: CFBundleVersion."
Return status of iTunes Transporter was 1: ERROR ITMS-90056: "This bundle Payload/Application.app/Frameworks/CryptorRSA.framework is invalid. The Info.plist file is missing the required key: CFBundleVersion."
The call to the iTMSTransporter completed with a non-zero exit status: 1. This indicates a failure.

Wrong interpretation of EVP_OpenInit in RSAData

On Linux, CryptorRSA.RSAData.decrypted() calls the openssl EVP_OpenInit function, but wrongly processes its return code:
https://github.com/IBM-Swift/BlueRSA/blob/1.0.21/Sources/CryptorRSA/CryptorRSA.swift#L417

The documentation for EVP_OpenInit states that it returns 0 on failure, or a positive integer on success matching the recovered secret key size. This matches the comment in the code, however the code's logic is inverted:

// EVP_OpenInit returns 0 on error or the recovered secret key size if successful
...
guard status != EVP_CIPHER_key_length(.make(optional: encType)) else {

Now for some reason, status is being returned as 1 in the success case (inconsistent with the documentation), so the logic above happens to work for success cases (because 1 is not equal to the key length). However, if EVP_OpenInit fails, 0 is also not equal to the key length, and so we erroneously carry on with decryption. This can result in a crash.

I'm not sure why the return value of EVP_OpenInit is inconsistent with the documentation, but I think the logic based on its observed behaviour should instead be:

guard status != 0 else {

(similar to EVP_OpenUpdate / EVP_OpenFinal).

CFString issue: The operation couldn't be completed. (CryptorRSA.CryptorRSA.Error error 1.)

Commit 842c82f removes "unneeded" CFString: Hashable extension (#70)

But that may not true. Some of our users reported that latest version of our Mac app shows an error:

The operation couldn't be completed. (CryptorRSA.CryptorRSA.Error error 1.)

It didn't happen on previous versions, and after revert to older commit ea8374b , our Mac app functional again.

CFString Hashable extension may be still required for some systems.

User environment:

  • Device: Mac mini (later 2014)
  • OS: macOS Big Sur 11.5
  • Process: 2.6 GHz Dual-Core intel Core i5

Development environment:

  • OS: macOS 11.5.1 (20G80)
  • Chip: Apple M1
  • Xcode Version 12.5.1 (12E507)
  • Swift 5.3

Swift 5.8.1 build issue Linux

There are some build issues for this package in Swift 5.8.1 (current release version). The issues I am seeing are as follows:

/var/www/project/.build/checkouts/BlueRSA/Sources/CryptorRSA/CryptorRSA.swift:476:61: error: cannot find 'EVP_PKEY_size' in scope
                                ek = UnsafeMutablePointer<UInt8>.allocate(capacity: Int(EVP_PKEY_size(.make(optional: key.reference))))
                                                                                        ^~~~~~~~~~~~~
/var/www/project/.build/checkouts/BlueRSA/Sources/CryptorRSA/CryptorRSA.swift:476:76: error: cannot infer contextual base in reference to member 'make'
                                ek = UnsafeMutablePointer<UInt8>.allocate(capacity: Int(EVP_PKEY_size(.make(optional: key.reference))))
                                                                                                      ~^~~~
/var/www/project/.build/checkouts/BlueRSA/Sources/CryptorRSA/CryptorRSA.swift:481:20: error: cannot find 'EVP_CIPHER_iv_length' in scope
                                let IVLength = EVP_CIPHER_iv_length(.make(optional: enc))
                                               ^~~~~~~~~~~~~~~~~~~~
/var/www/project/.build/checkouts/BlueRSA/Sources/CryptorRSA/CryptorRSA.swift:481:42: error: cannot infer contextual base in reference to member 'make'
                                let IVLength = EVP_CIPHER_iv_length(.make(optional: enc))
                                                                    ~^~~~
/var/www/project/.build/checkouts/BlueRSA/Sources/CryptorRSA/CryptorRSA.swift:688:28: error: cannot find 'EVP_PKEY_size' in scope
                                let encKeyLength = Int(EVP_PKEY_size(.make(optional: key.reference)))
                                                       ^~~~~~~~~~~~~
/var/www/project/.build/checkouts/BlueRSA/Sources/CryptorRSA/CryptorRSA.swift:688:43: error: cannot infer contextual base in reference to member 'make'
                                let encKeyLength = Int(EVP_PKEY_size(.make(optional: key.reference)))
                                                                     ~^~~~
/var/www/project/.build/checkouts/BlueRSA/Sources/CryptorRSA/CryptorRSA.swift:690:27: error: cannot find 'EVP_CIPHER_iv_length' in scope
                                let encIVLength = Int(EVP_CIPHER_iv_length(.make(optional: encType)))
                                                      ^~~~~~~~~~~~~~~~~~~~
/var/www/project/.build/checkouts/BlueRSA/Sources/CryptorRSA/CryptorRSA.swift:690:49: error: cannot infer contextual base in reference to member 'make'
                                let encIVLength = Int(EVP_CIPHER_iv_length(.make(optional: encType)))
                                                                           ~^~~~
/var/www/project/.build/checkouts/BlueRSA/Sources/CryptorRSA/CryptorRSA.swift:697:74: error: cannot convert value of type 'String' to expected argument type 'Data.Index' (aka 'Int')
                                let encryptedData = self.data.subdata(in: encKeyLength..<encKeyLength+encryptedDataLength)
                                                                                                     ^
/var/www/project/.build/checkouts/BlueRSA/Sources/CryptorRSA/CryptorRSA.swift:698:57: error: cannot convert value of type 'String' to expected argument type 'Data.Index' (aka 'Int')
                                let encryptedIV = self.data.subdata(in: encKeyLength+encryptedDataLength..<self.data.count)
                                                                                    ^

I also notice that this repo does not appear to be active, if this is the case can you let me know so I can look for an alternative.

*Please don't suggest that I create a pull request, there are currently three outstanding and no updates to the repo in 2 years.

Extra tests

  • both encryption and signature false tests. i.e. create signature, modify it and then try to verify
  • fixed encryption and signature tests:
  • fixed encryption and signature tests with data generated using cross library

Bug: strange path resolving in createXXXXX (withPEMNamed pemName: String, onPath path: String)

I may misunderstand something here, but when I build my the project the following code fails:
try CryptorRSA.createPrivateKey(withPEMNamed: "private.pem", onPath: "/Resources/")

trying to find the key file at that path:
<path_to_xcode_project_derived_data>/SourcePackages/checkouts/BlueRSA/Sources/CryptorRSA/CryptorRSAKey.swift/Resources/private_key.pem

Code causing the problem in createPrivateKey function:
let fullPath = URL(fileURLWithPath: #file).appendingPathComponent( path.appending(certName) ).standardized
Is appending path to CryptorRSAKey.swift file is supposed to be working?

Workaround is to get the content of a .pem file yourself:
try CryptorRSA.createPrivateKey(withPEM: privateKey())

The same problem with any createXXXXX (pemName/derName, onPath) function.

Linux. Crash when decrypting: "Fatal error: Can't form Range with upperBound < lowerBound"

OS: Linux
OpenSSL Version: 1.1.1

I am using the same exact code on MacOS and on Linux:

guard let decryptedData = try CryptorRSA.createEncrypted(with: data).decrypted(with: privateKey, algorithm: .sha1)?.data

I am attempting to decrypt data with a private key. It works properly on MacOS, but when running on Linux I get a crash with error:

Fatal error: Can't form Range with upperBound < lowerBound: file Swift/Range.swift, line 728

I noticed this is coming from line 697 in Sources/CryptorRSA.swift during the step with the comment "Extract encryptedKey, encryptedData, encryptedIV from data"

How to fetch/get final encrypted data

Below is my code

let publicKey = try? CryptorRSA.createPublicKey(withBase64: serverPublicKey)
let myPlaintext = try? CryptorRSA.createPlaintext(with: "Admin@123", using: String.Encoding.utf8)
let encryptedData = try? myPlaintext?.encrypted(with: publicKey!, algorithm: .sha1)
Using "encryptedData" as above , how to get the encrypted data.

CMS Signatures

Would it be possible to get CMS/PKCS#7 signatures (both attached and detached) added to BlueRSA? This would be useful for signing MDM payloads, validating AppStore receipts, etc. It's also unsupported by any Swift Linux framework.

Potential side-channels during en-/decoding of private-key

There are multiple places where an RSA private-key is encoded or decoded with Base64 using standard Swift library functions. Since these functions do not guarantee constant-time processing of the input, there is a potential side-channel that may leak information about the private-key.

I did not investigate the code thoroughly, but here are the potentially insecure uses I found at first glance:

https://github.com/IBM-Swift/BlueRSA/blob/9435e102af2838aa29c1f52a843ee1886876c379/Sources/CryptorRSA/CryptorRSAKey.swift#L392

https://github.com/IBM-Swift/BlueRSA/blob/9435e102af2838aa29c1f52a843ee1886876c379/Sources/CryptorRSA/CryptorRSAKey.swift#L631

https://github.com/IBM-Swift/BlueRSA/blob/9435e102af2838aa29c1f52a843ee1886876c379/Sources/CryptorRSA/CryptorRSAKey.swift#L676

https://github.com/IBM-Swift/BlueRSA/blob/9435e102af2838aa29c1f52a843ee1886876c379/Sources/CryptorRSA/CryptorRSAKey.swift#L739

Update to use SecKeyCreateRandomKey

iOS 15.0 deprecated SecKeyGeneratePair, so would appreciate updating to SecKeyCreateRandomKey to eliminate a warning.

Pretty easy to change over -

    var privateKey: SecKey?
    var publicKey: SecKey?

    do {
        var error: Unmanaged<CFError>?

        // The keys are automatically stored in the keychain
        guard let privKey = SecKeyCreateRandomKey(attributes as CFDictionary, &error) else {
            throw error!.takeRetainedValue() as Error
        }
        privateKey = privKey
        publicKey = SecKeyCopyPublicKey(privateKey!)
    } catch {
        ulog.error(error: error, "Error creating public/private keys")
    }

iOS not supported in the podspec

When trying to use the BlueRSA pod for iOS I get the following error:

The platform of the target `CocoapodsTest` (iOS 12.0) is not compatible with `BlueRSA (1.0.17)`, which does not support `ios`

when comparing the podspec of BlueRSA to BlueCryptor I saw that:

s.ios.deployment_target = "10.0"

Was missing. In the readme it states the BlueRSA runs on iOS 10 or higher so I would expect this to work.

There is not a reference to the BlueRSA pod but I assume it is intended to support this?

Store EVP key instead of RSA in key.reference

It is recommended that we use EVP functions instead of RSA and EVP functions take in EVP keys. Right now I am converting the RSA key into EVP every time I want to use to use it. This is inefficient.

                // convert RSA key to EVP
                let  evp_key = EVP_PKEY_new()
                EVP_PKEY_set1_RSA(evp_key, key.reference)

creating a symmetric public/private key

Hi there,

can I use this lib also to generate a certificate with a private key that was created?
Something like:

let keypair = try CryptorRSA.makeKeyPair(CryptorRSA.RSAKey.KeySize.bits2048)
var cert = createCertificate()
cert.publicKey = keypair.publicKey
cert.sign(keypair.privateKey, sha256)

is it possible?
thanks

Use of DER in OpenSSL

Right now when a DER encoded key is being used in OpenSSL, we convert to PEM and then create an RSA object from the PEM data.
OpenSSL has d2i_PrivateKey_bio which can be used directly for DER data.

Investigate if it's a good idea to use that instead of only PEM.

Crash while creating private key with Base64 string on Linux

I removed header and footer lines in my private key file and use:

let privateKey = try CryptorRSA.createPrivateKey(withBase64: base64String)

it works well on Mac OS but on Linux it crashes with error:

Fatal error: Unexpectedly found nil while unwrapping an Optional value

Memory Leaks on Linux

We had reports of Memory leaks when signing/verifying a with Swift-JWT. We recreated this on our own repo JWT along with encryption and decryption. This produced the following memory report: leaks.txt which highlights leaks at:

evp_key = .init(PEM_read_bio_PUBKEY(bio, nil, nil, nil))

This is due to the evp_key not being properly freed after it was referenced by:

var pkey_ctx = EVP_PKEY_CTX_new(evp_key, nil)

(Mirrored for private key).

There are also leaks in encrypt and decrypt where allocated memory from pointers wasn't being deallocated.

Is it possible to decrypt the data using Public Key?

I have a situation like, server will send the encrypted data (Encrypt Using Private Key), I have to decrypt the data using the Public Key(PEM File)

Please refer this image below,
NEpCl

The First way is pretty clear. The second path is little bit confused.

Based on my search, This seems to be bad idea to have a public key to decrypt the information. But in Other platforms they can do the same.

Help me! Thanks in advance.

New Release

Would it be possible to create a new release that contains #70.

Our Project is using https://github.com/Kitura/Swift-JWT which references this repository. Therefore we need a new version of this package to be published in order that the fix will get included.

Thanks for your work.

Linux compile error converting UnsafePointer<UInt8>

Building as part of a docker deploy on Bluemix. (ibmcom/swift-ubuntu:4.1.1)

Error message:
CryptorRSA.swift:618:58: error: cannot convert value of type 'UnsafePointer' to expected argument type 'UnsafeMutablePointer!'
return EVP_DigestVerifyFinal(md_ctx, sig, signature.data.count)
^~~~~~~

Issue building release with CryptorRSA | Xcode 14.3

I am trying to build a release xcframework for distribution that uses SwiftJWT via Swift Package Manager:
Screenshot 2023-04-06 at 4 45 15 PM

I am able to build fine confirmed for Xcode 14.2.0, 14.0.1, 13.4.1, 13.2.1, and 13.1.0. But when I try building with Xcode 14.3, I get the following error:

** ARCHIVE FAILED **


The following build commands failed:
	SwiftVerifyEmittedModuleInterface normal arm64 Verifying\ emitted\ module\ interface\ CryptorRSA.private.swiftinterface /Users/tj/Library/Developer/Xcode/DerivedData/VNWebSDK-fwdasyvrfoacjledmziziwepgjrj/Build/Intermediates.noindex/ArchiveIntermediates/VNWebSDK/IntermediateBuildFilesPath/CryptorRSA.build/Release-iphoneos/CryptorRSA.build/Objects-normal/arm64/CryptorRSA.private.swiftinterface (in target 'CryptorRSA' from project 'CryptorRSA')
	SwiftVerifyEmittedModuleInterface normal arm64 Verifying\ emitted\ module\ interface\ CryptorRSA.swiftinterface /Users/tj/Library/Developer/Xcode/DerivedData/VNWebSDK-fwdasyvrfoacjledmziziwepgjrj/Build/Intermediates.noindex/ArchiveIntermediates/VNWebSDK/IntermediateBuildFilesPath/CryptorRSA.build/Release-iphoneos/CryptorRSA.build/Objects-normal/arm64/CryptorRSA.swiftinterface (in target 'CryptorRSA' from project 'CryptorRSA')
(2 failures)

I've tried several things, like setting -Xfrontend -module-interface-preserve-types-as-written in OTHER_SWIFT_FLAGS and excluding architectures. I can't get it to work.

Could this be due to a conflict/duplication between a module and class name inside of CryptorRSA, or is there something I can do to get this to build the xcframework in Xcode 14.3?

Bug: Key creation failure if byte 27 of key data is 0x30

If you try to create an RSA key with data where byte 27 happens to be 0x30, key creation fails.

I tracked this down to an unsafe assumption in the stripX509CertificateHeader function:
https://github.com/IBM-Swift/BlueRSA/blob/master/Sources/CryptorRSA/CryptorRSAUtilities.swift#L228
which is called here:
https://github.com/IBM-Swift/BlueRSA/blob/master/Sources/CryptorRSA/CryptorRSAKey.swift#L624

I found this while debugging intermittent test failures in the CI. The symptom on Linux is a crash because we don't handle a failure from OpenSSL properly - I have a fix for that in the issue.swift51 branch, but I haven't figured out what to do about this problem yet.

what is error code -50?

getting this error when trying to decrypt.

Error Domain=NSOSStatusErrorDomain Code=-50 "RSA-WRAP too short input data" UserInfo={NSDescription=RSA-WRAP too short input data}

how should I resolve it????

Encrypted data cannot be shared between MacOS and Linux

When you encrypt some data using a public key on MacOS into an Encrypted data, you can decrypt this data on MacOS, However if you try to decrypt the same data on Linux it doesn't work. This means that is data is encrypted on MacOS it cannot be decrypted on Linux.

You can replicate this with the following code:

let publicKey = """
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDpbnF5g5bt9mjweE5nZioLAPKI
l31qj5/ht4i62gsEg/6R/GMBIAhUEgfr9n3H0jIKRoI0BvVH6+fUB9pKoMUdRu3V
sAF9ExkuhwazpE1uIfRbf2IJHIAz5zX3emUdymHaPZPucQUF7G/XmOMK86qKl8Zd
d8Gl8cTFpRVMoSs4lwIDAQAB
-----END PUBLIC KEY-----
"""

let privateKey = """
-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQDpbnF5g5bt9mjweE5nZioLAPKIl31qj5/ht4i62gsEg/6R/GMB
IAhUEgfr9n3H0jIKRoI0BvVH6+fUB9pKoMUdRu3VsAF9ExkuhwazpE1uIfRbf2IJ
HIAz5zX3emUdymHaPZPucQUF7G/XmOMK86qKl8Zdd8Gl8cTFpRVMoSs4lwIDAQAB
AoGAcs/ZjDTGxWAPGUdy+LRtNWBP6hLoosLllnVZEN4x0RTC3zbN0z3YGtGLh+mC
0Ad4iUlIvSI2/hrvuX/rRA1zJRSWqmUi+K/IQtRqH4L29xfDT9yxVd5X61vb5dGs
nruBHBSdcfsLKrQZClAqGKNElVfLn5+vaf48hsm9de5lSRECQQD+WcQHRSEyuuWl
dW0qhfRBXjtqnvS1VQ+CmS4nzeAVfNLV8KzJvx/evoQ9KxbnwfN/fQkyniK0RzNs
kcXNZFsLAkEA6vHzWrQVtiQ5b8itwn3er7FWWy53SFLiy2MJCUBmm0Z2uJXox4Ym
nH2SoUVMHJOvqgdqcwz53RJIlMPkAMgwJQJAbYTDZon6qHhXR65PSh8RtE/Z76fw
IGA25HoGqLb6BOaRdfNCwz/bfjK0iA4Ut8gIi92P5062DMAXwWjnLfBHTwJBAM0E
p2xeO5f+0lQ2lVJkDj/Yi1f0G0j0c04yNL9rAF69RXpb7o62BNmIRr0OQJWrVp4T
7JNLHnsIqmeO7Va1WjUCQQDcY8s947hfiISXQ9o6auz33WyIRQWt/x0WdujVsxjM
JNHkkGxCfEjy9Z74EO8MoSddiM4+u7gPZsr5f6AZvMsj
-----END RSA PRIVATE KEY-----
"""

// Generate encrypted data
let key = try CryptorRSA.createPublicKey(withPEM: publicKey)
            let plaintext = try CryptorRSA.createPlaintext(with: "Hello World", using: .utf8)
            let encrypted = try plaintext.encrypted(with: key, algorithm: .sha256)

// encrypted.base64String on linux (216 char)
let linuxEncryptedHelloWorld = "VyG6sYjAAH3FtuOfN5BJWnScjVl5gAXTfThXbFNA0pU50pgPXEffV+T/4e9CchWHp6/8gpKNfuP7J2ly5577zwxnsLTHU3K2VlH2eq4UMEmKi3aZ9sUVzea3I5xvIoBVK0JVluNW4Wjld8Er1dB/1ZDwN94Qq9/TamNhiTD4a10XN5byzBn5D+lOFJ6RTk16Z4svXV3OjjvANYowxvXIeg=="

// encrypted.base64String on mac (208 char)
let macEncryptedHelloWorld = "JaLeZ4VhVoAENpa7EZZhsUpm2YmzfG9L496m0rtau4vR6wGKZ432l0xcfOkYjZeGN93/Fav82VNQEDonrWCUjEQuiodapbyne2r3HElhPwbbtEBVqeSI3XmJwTE8PH3Q7qGH9DxPxZf0dEhQAyoYNKQHVr4vumYanDNR+rGSvIQqPW37+JIt1zb0wjFaJVRUUsB8ELQzRD0yogM="

if let decryptedString = self.decrypt(base64EncryptedData: linuxEncryptedHelloWorld) {
    print("Successfully decrypted the Linux encrypted word: \(decryptedString)")
}
if let decryptedString = self.decrypt(base64EncryptedData: macEncryptedHelloWorld) {
    print("Successfully decrypted the Mac encrypted word: \(decryptedString)")
}
// Only the operating system you are currently running will be able to decode the encrypted word

On linux OpenSSL envelopes are used similar to this article
On mac Security is used similar to this article

I did notice that the aes digest is different here. However, when you change to EVP_aes_128_gcm() the test fail.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.