Skip to content

Commit 352ed15

Browse files
committed
drop SEM and SMSV
1 parent c9d67a9 commit 352ed15

File tree

3 files changed

+42
-358
lines changed

3 files changed

+42
-358
lines changed

README.md

Lines changed: 1 addition & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
SwCrypt
44
=========
55

6-
### Create public and private keys in DER format
6+
### Create public and private RSA keys in DER format
77
```
88
let (privateKey, publicKey) = try! CC.RSA.generateKeyPair(2048)
99
```
@@ -91,69 +91,8 @@ try SwKeyStore.upsertKey(privateKeyPEM, keyTag: "priv", options: [kSecAttrAccess
9191
try SwKeyStore.getKey("priv")
9292
try SwKeyStore.delKey("priv")
9393
```
94-
95-
### Encrypt/decrypt message in SEM (Simple Encrypted Message) format
96-
(works with OpenSSL PEM formatted keys too)
97-
```
98-
//public enum AESMode : UInt8 {case aes128, aes192, aes256}
99-
//public enum BlockMode : UInt8 {case cbcSHA256, gcm}
100-
101-
let mode = SEM.Mode(aes:.aes256, block:.cbcSHA256)
102-
try SEM.encryptMessage(testMessage, pemKey: publicKey, mode: mode)
103-
try SEM.decryptMessage(encMessage, pemKey: privateKey)
104-
try SEM.encryptData(testData, pemKey: publicKey, mode: mode)
105-
try SEM.decryptData(encData, pemKey: privateKey)
106-
```
107-
108-
### Sign, verify messages with SMSV (Simple Message Sign and Verify)
109-
```
110-
let sign = try? SMSV.sign(testMessage, pemKey: priv)
111-
let verified = try? SMSV.verify(testMessage, pemKey: pub, sign: sign!)
112-
```
113-
11494
-----
11595

116-
SEM (Simple Encrypted Message) format
117-
-------------------------------------
118-
119-
When encrypting using a public key:
120-
121-
- Convert message to NSData using UTF8 encoding
122-
- Create message header :
123-
- Version indicator 1 byte (current: 0)
124-
- AES mode 1 byte
125-
- Cipher mode 1 byte
126-
- AES key (depends on aes mode - 16, 24, 32 byte)
127-
- IV (depends on cipher mode - 16, 12 byte)
128-
- Encrypt message header with the public key with OAEP padding (size = RSA key size)
129-
- Encrypt message with the chosen aes and cipher mode (calculate message auth tag with aData: encrypted header, and append to the encrypted message)
130-
- Append encrypted header and messsage
131-
- Base64 encode
132-
133-
When decrypting using a private key:
134-
135-
- Base64 decode
136-
- Decrypt the first block (RSA key size)
137-
- Read the message header (Version, AES mode, Cipher mode), AES key, IV
138-
- Decrypt message (check message auth with aData: encrypted header)
139-
- Convert NSData to string with UTF8 decoding
140-
141-
Simple Message Sign and Verify
142-
------------------------------
143-
144-
Sign:
145-
146-
- Convert message to NSData using UTF8 encoding
147-
- Sign with the private key using PSS padding with SHA512 digest
148-
- Base64 encode the sign
149-
150-
Verify:
151-
152-
- Base64 decode the sign
153-
- Convert message to NSData using UTF8 encoding
154-
- Verify with the public key using PSS padding with SHA512 digest
155-
156-
-----
15796

15897
Check availability
15998
---------------------

SwCrypt/SwCrypt.swift

Lines changed: 0 additions & 247 deletions
Original file line numberDiff line numberDiff line change
@@ -579,253 +579,6 @@ public class PEM {
579579

580580
}
581581

582-
//Simple Encrypted Message
583-
public class SEM {
584-
585-
public enum Error: ErrorType {
586-
case parse
587-
case unsupportedVersion
588-
case invalidKey
589-
case decode
590-
591-
public static var debugLevel = 1
592-
593-
init(_ type: Error, function: String = #function, file: String = #file, line: Int = #line) {
594-
self = type
595-
if Error.debugLevel > 0 {
596-
print("\(file):\(line): [\(function)] \(self._domain): \(self)")
597-
}
598-
}
599-
}
600-
601-
public enum AESMode: UInt8 {
602-
case aes128, aes192, aes256
603-
604-
var keySize: Int {
605-
switch self {
606-
case .aes128: return 16
607-
case .aes192: return 24
608-
case .aes256: return 32
609-
}
610-
}
611-
}
612-
613-
public enum BlockMode: UInt8 {
614-
case cbcSHA256, gcm
615-
616-
var ivSize: Int {
617-
switch self {
618-
case .cbcSHA256: return 16
619-
case .gcm: return 12
620-
}
621-
}
622-
}
623-
624-
public struct Mode {
625-
let version: UInt8 = 0
626-
let aes: AESMode
627-
let block: BlockMode
628-
public init() {
629-
aes = .aes256
630-
block = .cbcSHA256
631-
}
632-
public init(aes: AESMode, block: BlockMode) {
633-
self.aes = aes
634-
self.block = block
635-
}
636-
}
637-
638-
public static func encryptMessage(message: String, pemKey: String, mode: Mode) throws -> String {
639-
let data = message.dataUsingEncoding(NSUTF8StringEncoding)!
640-
let encryptedData = try encryptData(data, pemKey: pemKey, mode: mode)
641-
return encryptedData.base64EncodedStringWithOptions([])
642-
}
643-
644-
public static func decryptMessage(message: String, pemKey: String) throws -> String {
645-
guard let data = NSData(base64EncodedString: message, options: []) else {
646-
throw Error(.parse)
647-
}
648-
let decryptedData = try decryptData(data, pemKey: pemKey)
649-
guard let decryptedString = String(data: decryptedData, encoding: NSUTF8StringEncoding) else {
650-
throw Error(.parse)
651-
}
652-
return decryptedString
653-
}
654-
655-
public static func encryptData(data: NSData, pemKey: String, mode: Mode) throws -> NSData {
656-
let aesKey = CC.generateRandom(mode.aes.keySize)
657-
let iv = CC.generateRandom(mode.block.ivSize)
658-
let header = getMessageHeader(mode, aesKey: aesKey, iv: iv)
659-
guard let derKey = try? SwKeyConvert.PublicKey.pemToPKCS1DER(pemKey) else {
660-
throw Error(.invalidKey)
661-
}
662-
663-
let encryptedHeader = encryptHeader(header, derKey: derKey)
664-
let encryptedData = try! cryptAuth(.encrypt, blockMode: mode.block,
665-
data: data, aData: encryptedHeader, key: aesKey, iv: iv)
666-
667-
let result = NSMutableData(data: encryptedHeader)
668-
result.appendData(encryptedData)
669-
return result
670-
}
671-
672-
673-
public static func decryptData(data: NSData, pemKey: String) throws -> NSData {
674-
guard let derKey = try? SwKeyConvert.PrivateKey.pemToPKCS1DER(pemKey) else {
675-
throw Error(.invalidKey)
676-
}
677-
guard let (header, blockSize) = try? decryptHeader(data, derKey: derKey) else {
678-
throw Error(.decode)
679-
}
680-
let encryptedHeader = data.subdataWithRange(
681-
NSRange(location: 0, length: blockSize))
682-
let encryptedData = data.subdataWithRange(
683-
NSRange(location: blockSize, length: data.length - blockSize))
684-
685-
let headerBytes = header.bytesView
686-
guard header.length > 0 else { throw Error(.parse) }
687-
guard headerBytes[0] == 0 else { throw Error(.unsupportedVersion) }
688-
guard let (mode, aesKey, iv) = parseModeKeyIv(headerBytes) else { throw Error(.parse) }
689-
690-
guard let decrypted = try? cryptAuth(
691-
.decrypt, blockMode: mode.block, data: encryptedData, aData: encryptedHeader,
692-
key: aesKey, iv: iv) else {
693-
throw Error(.decode)
694-
}
695-
return decrypted
696-
}
697-
698-
private static func encryptHeader(data: NSData, derKey: NSData) -> NSData {
699-
return try! CC.RSA.encrypt(data, derKey: derKey, tag: NSData(), padding: .oaep, digest: .sha1)
700-
}
701-
702-
private static func decryptHeader(data: NSData, derKey: NSData) throws -> (NSData, Int) {
703-
return try CC.RSA.decrypt(data, derKey: derKey, tag: NSData(), padding: .oaep, digest: .sha1)
704-
}
705-
706-
private static func cryptAuth(opMode: CC.OpMode, blockMode: BlockMode, data: NSData, aData: NSData,
707-
key: NSData, iv: NSData) throws -> NSData {
708-
if blockMode == .cbcSHA256 {
709-
return try cryptAuth(
710-
opMode, blockMode: .cbc, hmacAlg: .sha256, data: data, aData: aData, key: key, iv:iv)
711-
} else { // GCM
712-
return try CC.cryptAuth(
713-
opMode, blockMode: .gcm, algorithm: .aes, data: data, aData: aData, key: key, iv: iv,
714-
tagLength: 16)
715-
}
716-
}
717-
718-
private static func cryptAuth(opMode: CC.OpMode, blockMode: CC.BlockMode, hmacAlg: CC.HMACAlg,
719-
data: NSData, aData: NSData, key: NSData, iv: NSData) throws -> NSData {
720-
if opMode == .encrypt {
721-
//encrypt then mac
722-
let encryptedData = try! CC.crypt(
723-
.encrypt, blockMode: blockMode, algorithm: .aes, padding: .pkcs7Padding,
724-
data: data, key: key, iv: iv)
725-
let macData = NSMutableData(data: aData)
726-
macData.appendData(encryptedData)
727-
let hmac = CC.HMAC(macData, alg: hmacAlg, key: key)
728-
let result = NSMutableData(data: encryptedData)
729-
result.appendData(hmac)
730-
return result
731-
} else {
732-
let encryptedData = data.subdataWithRange(NSRange(
733-
location:0, length: data.length - hmacAlg.digestLength))
734-
let macData = NSMutableData(data: aData)
735-
macData.appendData(encryptedData)
736-
737-
let hmac = data.subdataWithRange(NSRange(
738-
location: data.length - hmacAlg.digestLength, length: hmacAlg.digestLength))
739-
740-
guard CC.HMAC(macData, alg: hmacAlg, key: key) == hmac else {
741-
throw CC.CCError(.decodeError)
742-
}
743-
return try CC.crypt(
744-
.decrypt, blockMode: blockMode, algorithm: .aes, padding: .pkcs7Padding,
745-
data: encryptedData, key: key, iv: iv)
746-
}
747-
}
748-
749-
private static func getMessageHeader(mode: Mode, aesKey: NSData, iv: NSData) -> NSData {
750-
let modeData: [UInt8] = [mode.version, mode.aes.rawValue, mode.block.rawValue]
751-
let header = NSMutableData(bytes: modeData, length: modeData.count)
752-
header.appendData(aesKey)
753-
header.appendData(iv)
754-
return header
755-
}
756-
757-
private static func parseModeKeyIv(header: NSData.BytesView) -> (Mode, NSData, NSData)? {
758-
let modeLength = 3
759-
guard header.length > modeLength else {
760-
return nil
761-
}
762-
guard let aes = AESMode(rawValue: header[1]) else {
763-
return nil
764-
}
765-
guard let block = BlockMode(rawValue: header[2]) else {
766-
return nil
767-
}
768-
let keySize = aes.keySize
769-
let ivSize = block.ivSize
770-
guard header.length == modeLength + keySize + ivSize else {
771-
return nil
772-
}
773-
let key = header[modeLength ..< modeLength + keySize]
774-
let iv = header[modeLength + keySize ..< modeLength + keySize + ivSize]
775-
776-
return (Mode(aes: aes, block: block), key, iv)
777-
}
778-
779-
}
780-
781-
//Simple Message Sign and Verify
782-
public class SMSV {
783-
784-
public enum Error: ErrorType {
785-
case invalidKey
786-
case parseMessage
787-
788-
public static var debugLevel = 1
789-
790-
init(_ type: Error, function: String = #function, file: String = #file, line: Int = #line) {
791-
self = type
792-
if Error.debugLevel > 0 {
793-
print("\(file):\(line): [\(function)] \(self._domain): \(self)")
794-
}
795-
}
796-
}
797-
798-
public static func sign(message: String, pemKey: String) throws -> String {
799-
let data = message.dataUsingEncoding(NSUTF8StringEncoding)!
800-
let signedData = try signData(data, pemKey: pemKey)
801-
return signedData.base64EncodedStringWithOptions([])
802-
}
803-
804-
public static func signData(data: NSData, pemKey: String) throws -> NSData {
805-
guard let derKey = try? SwKeyConvert.PrivateKey.pemToPKCS1DER(pemKey) else {
806-
throw Error(.invalidKey)
807-
}
808-
return try! CC.RSA.sign(data, derKey: derKey, padding: .pss, digest: .sha512, saltLen: 16)
809-
}
810-
811-
public static func verify(message: String, pemKey: String, sign: String) throws -> Bool {
812-
let data = message.dataUsingEncoding(NSUTF8StringEncoding)!
813-
guard let signData = NSData(base64EncodedString: sign, options: []) else {
814-
throw Error(.parseMessage)
815-
}
816-
return try verifyData(data, pemKey: pemKey, signData: signData)
817-
}
818-
819-
public static func verifyData(data: NSData, pemKey: String, signData: NSData) throws -> Bool {
820-
guard let derKey = try? SwKeyConvert.PublicKey.pemToPKCS1DER(pemKey) else {
821-
throw Error(.invalidKey)
822-
}
823-
return try! CC.RSA.verify(
824-
data, derKey: derKey, padding: .pss, digest: .sha512, saltLen: 16, signedData: signData)
825-
}
826-
}
827-
828-
829582
public class CC {
830583

831584
public typealias CCCryptorStatus = Int32

0 commit comments

Comments
 (0)